[英]Pandas backfilling values based on a datetime index and a column
我有一个带有两组日期的Pandas
数据框,一个用于索引的DatetimeIndex
和一个名为date2
的列,其中包含datetime对象,一个值和一个id。 对于某些id,我缺少date2
等于索引的值,在这种情况下,我想用前一个DatetimeIndex和id的值填充行/值。 date1
表示当前时间点, date2
表示最后一个日期。 每个df[df.id == id]
可以被视为自己的数据帧,但数据存储在一个500k行的巨型数据帧中。
示例:给定
date2 id value
index
2006-01-24 2006-01-26 3 3
2006-01-25 2006-01-26 1 1
2006-01-25 2006-01-26 2 2
2006-01-26 2006-01-26 2 2.1
2006-01-27 2006-02-26 4 4
在此示例中,缺少id为1,id 2和id3的index == date2
行。 我想用前面的索引值回填每个缺失的行,该索引值分别对应于它的id。
我想回复:
date2 id value
index
2006-01-24 2006-01-26 3 3
2006-01-25 2006-01-26 1 1
2006-01-25 2006-01-26 2 2
2006-01-26 2006-01-26 1 1 #<---- row added
2006-01-26 2006-01-26 2 2.1
2006-01-26 2006-01-26 3 3 #<---- row added
2006-01-27 2006-02-26 4 4
2006-02-26 2006-02-26 4 4 #<---- row added
这不是很干净,但是可能的解决方案。 首先,我将索引移动到了一个列date1
:
In [228]: df
Out[228]:
date1 date2 id value
0 2006-01-24 2006-01-26 3 3.0
1 2006-01-25 2006-01-26 1 1.0
2 2006-01-25 2006-01-26 2 2.0
3 2006-01-26 2006-01-26 2 2.1
然后我按每对日期分组,为那些匹配的对添加id。 这涉及将DataFrame分解为子帧列表并使用concat
重新组合在一起。
In [229]: dfs = []
...: for (date1, date2), df_gb in df.groupby(['date1','date2']):
...: if date1 == date2:
...: to_add = list(set([1,2,3]) - set(df_gb['id']))
...: df_gb = df_gb.append(pd.DataFrame({'id': to_add, 'date1': date1, 'date2': date2, 'value': np.nan}), ignore_index=True)
...: dfs.append(df_gb)
In [231]: df = pd.concat(dfs, ignore_index=True)
In [232]: df
Out[232]:
date1 date2 id value
0 2006-01-24 2006-01-26 3 3.0
1 2006-01-25 2006-01-26 1 1.0
2 2006-01-25 2006-01-26 2 2.0
3 2006-01-26 2006-01-26 2 2.1
4 2006-01-26 2006-01-26 1 NaN
5 2006-01-26 2006-01-26 3 NaN
最后,我对缺失值进行了排序和填充。
In [233]: df = df.sort(['id', 'date1', 'date2'])
In [234]: df = df.fillna(method='ffill')
In [236]: df.sort(['date1', 'date2'])
Out[236]:
date1 date2 id value
0 2006-01-24 2006-01-26 3 3.0
1 2006-01-25 2006-01-26 1 1.0
2 2006-01-25 2006-01-26 2 2.0
4 2006-01-26 2006-01-26 1 1.0
3 2006-01-26 2006-01-26 2 2.1
5 2006-01-26 2006-01-26 3 3.0
我有点不愿回答b / c似乎@chrisb可能已经成功回答了原来的问题,后来改变了。 但是,Chris几天之内没有更新答案,这个答案确实采用了不同的方法,所以我要给Chris的答案+1并加上这个答案。
首先,只需使用'index'='date2'从原始数据框创建一个新的数据框。 这将是附加到现有数据框的基础(请注意,'index'是此处的列,而不是索引):
df2 = df[ df['index'] != df['date2'] ]
df2['index'] = df2['date2']
df2['value'] = np.nan
index date2 id value
0 2006-01-26 2006-01-26 3 NaN
1 2006-01-26 2006-01-26 1 NaN
2 2006-01-26 2006-01-26 2 NaN
4 2006-02-26 2006-02-26 4 NaN
现在,只需附加所有这些,但删除我们不需要的那些(如果我们已经有一个'index'='date2'的现有行,这里的id = 2):
df3 = df.append(df2)
df3 = df3.drop_duplicates(['index','date2','id'])
df3 = df3.reset_index(drop=True).sort(['id','index','date2'])
df3['value'] = df3.value.fillna(method='ffill')
index date2 id value
1 2006-01-25 2006-01-26 1 1.0
6 2006-01-26 2006-01-26 1 1.0
2 2006-01-25 2006-01-26 2 2.0
3 2006-01-26 2006-01-26 2 2.1
0 2006-01-24 2006-01-26 3 3.0
5 2006-01-26 2006-01-26 3 3.0
4 2006-01-27 2006-02-26 4 4.0
7 2006-02-26 2006-02-26 4 4.0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.