根据 pandas 中的 groupby 添加和填充数据框中日期的行
Adding and filling rows for dates in dataframe based on groupby in pandas
我有一个可以通过以下方式生成的数据框:
import pandas as pd
data = [['tom', 10, '20190202',5], ['nick', 15,'20190202',7], ['juli', 16,'20190203',8],
['tom', 17,'20190204',6], ['tom', 10,'20190204',9], ['nick', 15,'20190207',3]]
df = pd.DataFrame(data, columns = ['Employee', 'ID','Date','Value'])
数据框如下所示:
我需要这样的输出:
需要根据以下假设生成新的数据帧:
对于所有 "Employee" 和 "ID",找到最大日期,并且 "Employee" 和 "ID" 的前一个最后条目的数据在行中重复,直到达到最大日期。
首先创建 DatetimeIndex
DataFrame.set_index
and in GroupBy.apply
use custom lambda function with DataFrame.reindex
每个组的每个最小日期时间和列 Date
的最大日期时间,并向前填充缺失值:
#convert to datetimes if necessary
df['Date'] = pd.to_datetime(df['Date'])
df = (df.set_index('Date')
.groupby(['Employee', 'ID'], sort=False)['Value']
.apply(lambda x: x.reindex(pd.date_range(x.index.min(),
df['Date'].max(),
name='Date'), method='ffill'))
.reset_index())
print (df)
Employee ID Date Value
0 tom 10 2019-02-02 5
1 tom 10 2019-02-03 5
2 tom 10 2019-02-04 9
3 tom 10 2019-02-05 9
4 tom 10 2019-02-06 9
5 tom 10 2019-02-07 9
6 nick 15 2019-02-02 7
7 nick 15 2019-02-03 7
8 nick 15 2019-02-04 7
9 nick 15 2019-02-05 7
10 nick 15 2019-02-06 7
11 nick 15 2019-02-07 3
12 juli 14 2019-02-03 8
13 juli 14 2019-02-04 8
14 juli 14 2019-02-05 8
15 juli 14 2019-02-06 8
16 juli 14 2019-02-07 8
17 tom 14 2019-02-04 6
18 tom 14 2019-02-05 6
19 tom 14 2019-02-06 6
20 tom 14 2019-02-07 6
@jezrel 的回答非常有效。但只是为了让观众有多种选择也添加我的,因为这也是
df['Date']=pd.to_datetime(df['Date'])
def expand_dates(ser):
return pd.DataFrame({'Date': pd.date_range(ser['Date'].min(), df['Date'].max(), freq='D')})
newdf = df.groupby(['Employee', 'ID']).apply(expand_dates).reset_index()\
.merge(df, how='left')[['Employee', 'ID','Date','Value']].ffill()
我有一个可以通过以下方式生成的数据框:
import pandas as pd
data = [['tom', 10, '20190202',5], ['nick', 15,'20190202',7], ['juli', 16,'20190203',8],
['tom', 17,'20190204',6], ['tom', 10,'20190204',9], ['nick', 15,'20190207',3]]
df = pd.DataFrame(data, columns = ['Employee', 'ID','Date','Value'])
数据框如下所示:
我需要这样的输出:
需要根据以下假设生成新的数据帧: 对于所有 "Employee" 和 "ID",找到最大日期,并且 "Employee" 和 "ID" 的前一个最后条目的数据在行中重复,直到达到最大日期。
首先创建 DatetimeIndex
DataFrame.set_index
and in GroupBy.apply
use custom lambda function with DataFrame.reindex
每个组的每个最小日期时间和列 Date
的最大日期时间,并向前填充缺失值:
#convert to datetimes if necessary
df['Date'] = pd.to_datetime(df['Date'])
df = (df.set_index('Date')
.groupby(['Employee', 'ID'], sort=False)['Value']
.apply(lambda x: x.reindex(pd.date_range(x.index.min(),
df['Date'].max(),
name='Date'), method='ffill'))
.reset_index())
print (df)
Employee ID Date Value
0 tom 10 2019-02-02 5
1 tom 10 2019-02-03 5
2 tom 10 2019-02-04 9
3 tom 10 2019-02-05 9
4 tom 10 2019-02-06 9
5 tom 10 2019-02-07 9
6 nick 15 2019-02-02 7
7 nick 15 2019-02-03 7
8 nick 15 2019-02-04 7
9 nick 15 2019-02-05 7
10 nick 15 2019-02-06 7
11 nick 15 2019-02-07 3
12 juli 14 2019-02-03 8
13 juli 14 2019-02-04 8
14 juli 14 2019-02-05 8
15 juli 14 2019-02-06 8
16 juli 14 2019-02-07 8
17 tom 14 2019-02-04 6
18 tom 14 2019-02-05 6
19 tom 14 2019-02-06 6
20 tom 14 2019-02-07 6
@jezrel 的回答非常有效。但只是为了让观众有多种选择也添加我的,因为这也是
df['Date']=pd.to_datetime(df['Date'])
def expand_dates(ser):
return pd.DataFrame({'Date': pd.date_range(ser['Date'].min(), df['Date'].max(), freq='D')})
newdf = df.groupby(['Employee', 'ID']).apply(expand_dates).reset_index()\
.merge(df, how='left')[['Employee', 'ID','Date','Value']].ffill()