Python 仅在开始日期和结束日期之间按标识符对两列求和
考虑到我有以下几点: 数据帧:Python 仅在开始日期和结束日期之间按标识符对两列求和,python,pandas,dataframe,pandas-groupby,Python,Pandas,Dataframe,Pandas Groupby,考虑到我有以下几点: 数据帧: id enddate startdate ownerId value 1 2019-10-05 2019-10-05 10 105 2 2019-10-06 2019-10-05 10 240 3 2019-10-07 2019-10-05 10 420 4 2019-10-08
id enddate startdate ownerId value
1 2019-10-05 2019-10-05 10 105
2 2019-10-06 2019-10-05 10 240
3 2019-10-07 2019-10-05 10 420
4 2019-10-08 2019-10-08 10 470
5 2019-10-01 2019-10-01 11 320
6 2019-10-02 2019-10-01 11 18
7 2019-10-10 2019-10-10 12 50
8 2019-10-12 2019-10-10 12 412
9 2019-10-14 2019-10-10 12 398
10 2019-10-15 2019-10-12 12 320
我想做的是对endId位于同一所有者id的当前startId和当前endId之间的所有值列求和
输出应为:
id enddate startdate ownerId value output
1 2019-10-05 2019-10-05 10 105 105 # Nothing between 2019-10-05 and 2019-10-05
2 2019-10-06 2019-10-05 10 240 345 # Found 1 record (with id 1)
3 2019-10-07 2019-10-05 10 420 765 # Found 2 records (with id 1 and 2)
4 2019-10-08 2019-10-08 10 470 470 # Nothing else between 2019-10-08 and 2019-10-08
5 2019-10-01 2019-10-01 11 320 320 # Reset because Owner is different
6 2019-10-02 2019-10-01 11 18 338 # Found 1 record (with id 5)
7 2019-10-10 2019-10-10 12 50 50 # ...
8 2019-10-12 2019-10-10 12 412 462
9 2019-10-14 2019-10-10 12 398 860
10 2019-10-15 2019-10-12 12 320 1130 # Found 3 records between 2019-10-12 and 2019-10-15 (with id 8, 9 and 10)
我试图使用groupby.sum等,但我无法得到我需要的
您有什么建议吗?您可以在一条指令中完成:
df['output'] = df.apply(lambda row:
df[df.ownerId.eq(row.ownerId) & df.enddate.between(row.startdate, row.enddate)]
.value.sum(), axis=1)
您可以在一条指令中完成此操作:
df['output'] = df.apply(lambda row:
df[df.ownerId.eq(row.ownerId) & df.enddate.between(row.startdate, row.enddate)]
.value.sum(), axis=1)
如果数据集不太大,可以使用selfjoin:
df[['startdate','enddate']] = df[['startdate','enddate']].apply(pd.to_datetime)
df['output'] = (df.merge(df, on='ownerId', suffixes=('','_y'))
.query('startdate <= enddate_y <= enddate')
.groupby('id')['value_y']
.sum()
.to_numpy())
print(df)
如果数据集不太大,可以使用selfjoin:
df[['startdate','enddate']] = df[['startdate','enddate']].apply(pd.to_datetime)
df['output'] = (df.merge(df, on='ownerId', suffixes=('','_y'))
.query('startdate <= enddate_y <= enddate')
.groupby('id')['value_y']
.sum()
.to_numpy())
print(df)
起初我忽略了这个细节。现在我更正了我的解决方案。哇!我花了大约3个小时的时间试图让这项工作可能过于专注于groupby解决方案,这是一种错误的思维方式。。。谢谢你非常准确和快速的回答最初我错过了这个细节。现在我更正了我的解决方案。哇!我花了大约3个小时的时间试图让这项工作可能过于专注于groupby解决方案,这是一种错误的思维方式。。。谢谢你的准确快速的回答。非常感谢。事实上,这种方法非常有效。我仍然不确定为什么需要按id分组,因为在我的例子中,id是唯一的键。由于笛卡尔连接,这个合并selfjion解决方案将创建具有相同id的多行。因此,为了得到总数,您需要按ID分组。@Valdi_-Bo解决方案更好。非常感谢。事实上,这种方法非常有效。我仍然不确定为什么需要按id分组,因为在我的例子中,id是唯一的键。由于笛卡尔连接,这个合并selfjion解决方案将创建具有相同id的多行。所以,为了得到总和,你需要按ID分组。@Valdi_-Bo解决方案更好。