Python 使用重复的索引值填充组内缺少的日期和值
我正在尝试按用户组填充缺少的日期,但是我的一个索引列有重复的日期,因此我尝试使用唯一的日期并对其重新索引,然后出现长度不匹配错误。如何按天频率重新采样而不出现重复错误Python 使用重复的索引值填充组内缺少的日期和值,python,pandas,dataframe,Python,Pandas,Dataframe,我正在尝试按用户组填充缺少的日期,但是我的一个索引列有重复的日期,因此我尝试使用唯一的日期并对其重新索引,然后出现长度不匹配错误。如何按天频率重新采样而不出现重复错误 import pandas as pandas x = pandas.DataFrame({'user': ['a','a','b','b','a'], 'dt': ['2016-01-01','2016-01-02', '2016-01-05','2016-01-06','2016-01-06'], 'val': [1,33,
import pandas as pandas
x = pandas.DataFrame({'user': ['a','a','b','b','a'], 'dt': ['2016-01-01','2016-01-02', '2016-01-05','2016-01-06','2016-01-06'], 'val': [1,33,2,1,2]})
udates=x['dt'].unique()
x['dt'] = pandas.to_datetime(x['dt'])
dates = x.set_index(udates).resample('D').asfreq().index
users=x['user'].unique()
idx = pandas.MultiIndex.from_product((dates, users), names=['dt', 'user'])
x.set_index(['dt', 'user']).reindex(idx, fill_value=0).reset_index()
print(x)
期望输出
dt user val
0 2016-01-01 a 1
2 2016-01-02 a 33
4 2016-01-03 a 0
6 2016-01-04 a 0
8 2016-01-05 a 0
10 2016-01-06 a 2
1 2016-01-01 b 0
3 2016-01-02 b 0
5 2016-01-03 b 0
7 2016-01-04 b 0
9 2016-01-05 b 2
11 2016-01-06 b 1
以下是一种方法,重新为每个
用户编制索引,使其具有从最小日期到最大日期的日期范围:
# setup your dataframe as you had it before:
x = pandas.DataFrame({'user': ['a','a','b','b','a'], 'dt': ['2016-01-01','2016-01-02', '2016-01-05','2016-01-06','2016-01-06'], 'val': [1,33,2,1,2]})
udates=x['dt'].unique()
x['dt'] = pandas.to_datetime(x['dt'])
# fill with new dates:
filled_df = (x.set_index('dt')
.groupby('user')
.apply(lambda d: d.reindex(pd.date_range(min(x.dt),
max(x.dt),
freq='D')))
.drop('user', axis=1)
.reset_index('user')
.fillna(0))
>>> filled_df
user val
2016-01-01 a 1.0
2016-01-02 a 33.0
2016-01-03 a 0.0
2016-01-04 a 0.0
2016-01-05 a 0.0
2016-01-06 a 2.0
2016-01-01 b 0.0
2016-01-02 b 0.0
2016-01-03 b 0.0
2016-01-04 b 0.0
2016-01-05 b 2.0
2016-01-06 b 1.0
另一种方式不如@sacul优雅,但速度几乎相同
import pandas as pd
x = pd.DataFrame({'user': ['a','a','b','b','a'],
'dt': ['2016-01-01','2016-01-02',
'2016-01-05','2016-01-06','2016-01-06'],
'val': [1,33,2,1,2]})
users = pd.unique(x.user)
x.dt = pd.to_datetime(x.dt)
dates = pd.date_range(min(x.dt), max(x.dt))
x.set_index('dt', inplace=True)
df = pd.DataFrame(index=dates)
for u in users:
df[u] = x[x.user==u].val
df = df.unstack().reset_index()
df.rename(columns={'level_0': 'user',
'level_1': 'dt',
0: 'val'}, inplace=True)
df.val.fillna(0, inplace=True)
df.val = df.val.astype(int)
df = df[['dt', 'user', 'val']]
df:
谢谢,它可以工作,重置索引对用户有什么意义?不客气!实际上,您可以为索引的两个级别重置索引,我只是出于某种原因将您的dt
列保留为最终数据帧中的索引,但实际上这是不必要的。唯一的问题是,然后需要重命名结果列(但这不是一个很大的问题)
dt user val
0 2016-01-01 a 1
1 2016-01-02 a 33
2 2016-01-03 a 0
3 2016-01-04 a 0
4 2016-01-05 a 0
5 2016-01-06 a 2
6 2016-01-01 b 0
7 2016-01-02 b 0
8 2016-01-03 b 0
9 2016-01-04 b 0
10 2016-01-05 b 2
11 2016-01-06 b 1