Python 跨不同的时间线和位置使用多个条件创建新的数据帧
我有以下数据帧,其中有一个棘手的问题:Python 跨不同的时间线和位置使用多个条件创建新的数据帧,python,pandas,dataframe,time-series,Python,Pandas,Dataframe,Time Series,我有以下数据帧,其中有一个棘手的问题: Disease State Month Value Covid Texas 2020-03 2 Covid Texas 2020-04 3 Covid Texas 2020-05 4 Covid Texas 2020-08 3 Cancer Florida 2020-04
Disease State Month Value
Covid Texas 2020-03 2
Covid Texas 2020-04 3
Covid Texas 2020-05 4
Covid Texas 2020-08 3
Cancer Florida 2020-04 4
Covid Florida 2020-03 6
Covid Florida 2020-04 4
Flu Florida 2020-03 5
我必须列出连续3个月的值,并创建一个新的数据框。
但是,有一些条件:
Disease State Month ValueList
Covid Texas 2020-02 [0, 2, 3] (no dataset for Feb 20 but next two months are)
Covid Texas 2020-03 [2, 3, 4] (has values for 3 consecutive months)
Covid Texas 2020-04 [3, 4, 0] (doesn’t have value for 6th month)
Covid Texas 2020-05 [4, 0, 0] (has value for present month)
Covid Texas 2020-06 [0, 0, 3] (has value for 8th month)
Covid Texas 2020-07 [0, 3, 0] (has value for 8th month)
Covid Texas 2020-08 [3, 0, 0] (has value for present month)
Covid Texas 2020-09 [0, 0, 0] (no dataset for next 3 months)
Covid Texas 2020-10 [0, 0, 0] (no dataset for next 3 months)
Covid Texas 2020-11 [0, 0, 0] (no dataset for next 3 months)
Covid Texas 2020-12 [0, 0, 0] (no dataset for next 3 months)
Covid Texas 2021-01 [0, 0, 0] (no dataset for next 3 months)
Covid Texas 2021-02 [0, 0, 0] (no dataset for next 3 months)
Covid Texas 2021-03 [0, 0, 0] (no dataset for next 3 months)
Covid Texas 2021-04 [0, 0, 0] (no dataset for next 3 months)
我试图用以下方式填写日期:
df3= (df2.set_index('MonthEnd')
.groupby(['Disease', 'State']).apply(lambda x: x.drop(['Disease', 'State'], axis=1).asfreq('D'))
.reset_index())
但是,它不会为每个组返回相同的时间帧。它返回该组中最小日期和最大日期之间的值
我不知道该怎么开始。任何帮助都将不胜感激。谢谢 让我们从简单的逻辑开始。因此,基本上您希望为每个组创建从2020年2月到2021年4月的日期范围
def fill_missing(group):
group = group.merge(pd.DataFrame({'Month': dates}), how='right')
group[['Disease', 'State']] = group[['Disease', 'State']].ffill().bfill()
group['Value'] = group['Value'].fillna(0)
group['ValueList'] = [[a, b, c] for a, b, c in zip(group['Value'].astype(int), group['Value'].shift(-1).fillna(0).astype(int), group['Value'].shift(-2).fillna(0).astype(int))]
return group
df_ = df.groupby(['Disease', 'State']).apply(fill_missing).reset_index(drop=True)
让我们以每组为例,使用reindex添加此日期范围。一旦我完成添加日期范围,现在我将填充数据,然后执行滚动功能以获得3个连续值(考虑前一个值和当前值),并将其转换为列表
我将把这些列表值分配给我的ValueList
列。
然后我将把所有这些修改过的组添加到dataframe
解决方案:
df.Month = pd.to_datetime(df.Month, format="%Y-%m")
df.set_index('Month',inplace=True)
def add_elem(li): # this is to add 0 elements if rolling function is not getting 2 previous rows.
n = (3-len(li))
if n<3:
li = [0]*n +li
return li
start = '2020-02'
end = '2021-04'
data = pd.DataFrame()
for i,grp in df.groupby(['Disease', 'State']):
grp = (grp.reindex(pd.date_range(start=start, end=end, freq="MS")))
grp[['Disease', 'State']] = grp[['Disease', 'State']].bfill().ffill()
grp = (grp.fillna(0))
grp['Value'] = grp['Value'].astype(int)
grp['ValueList'] = ([add_elem(window.to_list()) for window in grp['Value'].rolling(3)])
data = data.append(grp)
数据:
df.Month = pd.to_datetime(df.Month, format="%Y-%m")
df.set_index('Month',inplace=True)
def add_elem(li): # this is to add 0 elements if rolling function is not getting 2 previous rows.
n = (3-len(li))
if n<3:
li = [0]*n +li
return li
start = '2020-02'
end = '2021-04'
data = pd.DataFrame()
for i,grp in df.groupby(['Disease', 'State']):
grp = (grp.reindex(pd.date_range(start=start, end=end, freq="MS")))
grp[['Disease', 'State']] = grp[['Disease', 'State']].bfill().ffill()
grp = (grp.fillna(0))
grp['Value'] = grp['Value'].astype(int)
grp['ValueList'] = ([add_elem(window.to_list()) for window in grp['Value'].rolling(3)])
data = data.append(grp)
疾病
陈述
价值
估价单
2020-02-01
巨蟹座
佛罗里达州
0
[0, 0, 0]
2020-03-01
巨蟹座
佛罗里达州
0
[0, 0, 0]
2020-04-01
巨蟹座
佛罗里达州
4.
[0, 0, 4]
2020-05-01
巨蟹座
佛罗里达州
0
[0, 4, 0]
2020-06-01
巨蟹座
佛罗里达州
0
[4, 0, 0]
2020-07-01
巨蟹座
佛罗里达州
0
[0, 0, 0]
2020-08-01
巨蟹座
佛罗里达州
0
[0, 0, 0]
2020-09-01
巨蟹座
佛罗里达州
0
[0, 0, 0]
2020-10-01
巨蟹座
佛罗里达州
0
[0, 0, 0]
2020-11-01
巨蟹座
佛罗里达州
0
[0, 0, 0]
2020-12-01
巨蟹座
佛罗里达州
0
[0, 0, 0]
2021-01-01
巨蟹座
佛罗里达州
0
[0, 0, 0]
2021-02-01
巨蟹座
佛罗里达州
0
[0, 0, 0]
2021-03-01
巨蟹座
佛罗里达州
0
[0, 0, 0]
2021-04-01
巨蟹座
佛罗里达州
0
[0, 0, 0]
2020-02-01
冠状病毒
佛罗里达州
0
[0, 0, 0]
2020-03-01
冠状病毒
佛罗里达州
6.
[0, 0, 6]
2020-04-01
冠状病毒
佛罗里达州
4.
[0, 6, 4]
2020-05-01
冠状病毒
佛罗里达州
0
[6, 4, 0]
2020-06-01
冠状病毒
佛罗里达州
0
[4, 0, 0]
2020-07-01
冠状病毒
佛罗里达州
0
[0, 0, 0]
2020-08-01
冠状病毒
佛罗里达州
0
[0, 0, 0]
2020-09-01
冠状病毒
佛罗里达州
0
[0, 0, 0]
2020-10-01
冠状病毒
佛罗里达州
0
[0, 0, 0]
2020-11-01
冠状病毒
佛罗里达州
0
[0, 0, 0]
2020-12-01
冠状病毒
佛罗里达州
0
[0, 0, 0]
2021-01-01
冠状病毒
佛罗里达州
0
[0, 0, 0]
2021-02-01
冠状病毒
佛罗里达州
0
[0, 0, 0]
2021-03-01
冠状病毒
佛罗里达州
0
[0, 0, 0]
2021-04-01
冠状病毒
佛罗里达州
0
[0, 0, 0]
2020-02-01
冠状病毒
得克萨斯州
0
[0, 0, 0]
2020-03-01
冠状病毒
得克萨斯州
2.
[0, 0, 2]
2020-04-01
冠状病毒
得克萨斯州
3.
[0, 2, 3]
2020-05-01
冠状病毒
得克萨斯州
4.
[2, 3, 4]
2020-06-01
冠状病毒
得克萨斯州
0
[3, 4, 0]
2020-07-01
冠状病毒
得克萨斯州
0
[4, 0, 0]
2020-08-01
冠状病毒
得克萨斯州
3.
[0, 0, 3]
2020-09-01
冠状病毒
得克萨斯州
0
[0, 3, 0]
2020-10-01
冠状病毒
得克萨斯州
0
[3, 0, 0]
2020-11-01
冠状病毒
得克萨斯州
0
[0, 0, 0]
2020-12-01
冠状病毒
得克萨斯州
0
[0, 0, 0]
2021-01-01
冠状病毒
得克萨斯州
0
[0, 0, 0]
2021-02-01
冠状病毒
得克萨斯州
0
[0, 0, 0]
2021-03-01
冠状病毒
得克萨斯州
0
[0, 0, 0]
2021-04-01
冠状病毒
得克萨斯州
0
[0, 0, 0]
2020-02-01
流感
佛罗里达州
0
[0, 0, 0]
2020-03-01
流感
佛罗里达州
5.
[0, 0, 5]
2020-04-01
流感
佛罗里达州
0
[0, 5, 0]
2020-05-01
流感
佛罗里达州
0
[5, 0, 0]
2020-06-01
流感
佛罗里达州
0
[0, 0, 0]
2020-07-01
流感
佛罗里达州
0
[0, 0, 0]
2020-08-01
流感
佛罗里达州
0
[0, 0, 0]
2020-09-01
流感
佛罗里达州
0
[0, 0, 0]
2020-10-01
流感
佛罗里达州
0
[0, 0, 0]
2020-11-01
流感
佛罗里达州
0
[0, 0, 0]
2020-12-01
流感
佛罗里达州
0
[0, 0, 0]
2021-01-01
流感
佛罗里达州
0
[0, 0, 0]
2021-02-01
流感
佛罗里达州
0
[0, 0, 0]
2021-03-01
流感
佛罗里达州
0
[0, 0, 0]
2021-04-01
流感
佛罗里达州
0
[0, 0, 0]
您可以使用生成2020年2月至2021年4月之间的日期列表
dates=pd.date\u范围('2020-02','2021-04',freq='MS').strftime('%Y-%m'))
然后按Disease
和State
列分组,并填充每组中缺失的部分
def fill_missing(group):
group = group.merge(pd.DataFrame({'Month': dates}), how='right')
group[['Disease', 'State']] = group[['Disease', 'State']].ffill().bfill()
group['Value'] = group['Value'].fillna(0)
group['ValueList'] = [[a, b, c] for a, b, c in zip(group['Value'].astype(int), group['Value'].shift(-1).fillna(0).astype(int), group['Value'].shift(-2).fillna(0).astype(int))]
return group
df_ = df.groupby(['Disease', 'State']).apply(fill_missing).reset_index(drop=True)
签出groupby()并使用此选项填写缺少的日期。您可以使用apply()和groupby()来为每个组添加缺少的日期。一旦分组并添加了日期,您必须每三行迭代并选择一次:对您的Valuelist使用类似df.Value.tolist()的内容columns@JonathanLeon:谢谢你的回复。你能不能也分享一下其他的例子。不幸的是现在不行。在这个问题中,你有很多个人问题。从搜索groupby和apply开始,学习如何迭代和应用函数。我建议你自己尝试一下,并在过程的每一部分提出问题,说明你在哪里尝试过。人们更倾向于帮助修改代码,而不仅仅是提供代码。我已经添加了逻辑。对于我提供的解决方案,可能会有更好的解决方案,但逻辑将保持不变。您好@Pygirl,再次感谢您提供的详细解释。查找类型错误:传递PeriodType数据无效。使用
data.to_timestamp()
instead@Roy:请参阅:Hi@Ynjxsjmh。非常感谢你。这种逻辑确实令人印象深刻。在这里,我发现ValueError:您试图在句点[M]和对象列上合并。如果您希望继续,则应使用pd。concat@Roy可能正在将Month
列转换为df['Month']=df['Month'].astype(str)
字符串。