我正试图弄清楚特定用户何时首次达到既定目标。作为一个简化版本,我有2个数据集(1个捐款和1个筹款人)
import pandas as pd
import numpy as np
Donations = pd.DataFrame({
"id": pd.Series([1,2,3,4,5,6,7,8,9,10]),
"amount": pd.Series([10, 15, 10, 15, 10, 20, 70, 20,20,30]),
"solicitor": pd.Series([1, 1, 2, 2, 3, 4, 5, 1,1,2]),
"day": ([1,2,1,2,2,3,2,4,5,5]),
})
Fundraisers = pd.DataFrame({
"id": pd.Series([1,2,3,4,5]),
})
所以假设目标是30,我想找到第一天每个筹款人至少筹集到30美元。我通过使用groupby和for循环实现了这一点
def test(group, amount):
group = group.sort("day")
myamount = 0
date = np.NaN
for i in group.index:
myamount = myamount + group.loc[i, "amount"]
if (myamount >= amount):
date = group.loc[i, "day"]
break
return date
Fundraisers = Fundraisers.set_index(['id'])
Fundraisers["first day"] = Donations.groupby(["solicitor"]).apply(lambda x: test(x, 30))
Fundraisers = Fundraisers.reset_index()
我只是觉得有一种更好的方法可以做到这一点,而不是使用for循环来处理每一笔捐款。所以想知道是否有更好的方法来解决这个问题?
首先我假设筹款人的id是唯一的,因此我建议您使用该id作为索引。在你的例子中,我会这样做:
Fundraisers = pd.DataFrame(index= pd.Series([1,2,3,4,5]))
然后我建议你一个代码,比如:
Donations.sort("day",inplace=True)
cumulative_amount = Donations.groupby('solicitor').amount.cumsum()
Fundraisers['first day'] = Donations[cumulative_amount>=30].groupby('solicitor').min().day
那它呢?