我的奶奶有一些奇怪的想法。每个生日她带我去购物。 她有一些严格的规定。如果我买一件不到20美元的礼物,她就不会捐款。如果我花费超过20美元,她将捐赠高达30美元。
因此,如果礼物售价27美元,她将捐出7美元。
现在这让我花了23美元用于生日那天的额外礼物;与上述相同的规则适用于任何其他礼物。
一旦花了30美元,老奶奶就没有更多的贡献,我必须自己支付剩余的费用。
以下是我11岁,12岁和13岁生日的示例表。
DollarsSpent granny_pays
BirthDayAge PresentNum
11 1 25.00 5.00 -- I used up $5
2 100.00 25.00 -- I used up last $20
3 10.00 0.00
4 50.00 0.00
12 1 39.00 19.00 -- I used up $19 only $11 left
2 7.00 0.00
3 32.00 11.00 -- I used up the last $11 despite $12 of $32 above the $20 starting point
4 19.00 0.00
13 1 21.00 1.00 -- used up $1
2 27.00 7.00 -- used up $7, total used up $8 and never spent last $22
所以在大熊猫中我已经走到了这一步。
import pandas as pd
granny_wont_pay_first = 20.
granny_limit = 30.
df = pd.DataFrame({'BirthDayAge' : ['11','11','11','11','12','12','12','12','13','13']
,'PresentNum' : [1,2,3,4,1,2,3,4,1,2]
,'DollarsSpent' : [25.,100.,10.,50.,39.,7.,32.,19.,21.,27.]
})
df.set_index(['BirthDayAge','PresentNum'],inplace=True)
df['granny_pays'] = df['DollarsSpent'] - granny_wont_pay_first
df['granny_limit'] = granny_limit
df['zero'] = 0.0
df['granny_pays'] = df[['granny_pays','zero','granny_limit']].apply(np.median,axis=1)
df.drop(['granny_limit','zero'], axis=1, inplace=True)
print df.head(len(df))
这是输出。使用3个数字的中位数是一个很好的方法来计算出奶奶会贡献什么。
问题在于,您可以看到每个礼物都是孤立对待的,而且我并没有正确地侵蚀每个BirthDayAge中每个礼物的30美元。
DollarsSpent granny_pays
BirthDayAge PresentNum
11 1 25.00 5.00
2 100.00 30.00 -- should be 25.0
3 10.00 0.00
4 50.00 30.00 -- should be 0.0
12 1 39.00 19.00
2 7.00 0.00
3 32.00 12.00 -- should be 11.0
4 19.00 0.00
13 1 21.00 1.00
2 27.00 7.00
试着想出一个好的熊猫方法来做这种侵蚀。
希望没有循环。
答案 0 :(得分:4)
我不知道是否有更简洁的方法,但这应该有效并且确实避免了所要求的循环。
df['per_gift'] = df.DollarsSpent - 20
df['per_gift'] = np.where( df.per_gift > 0, df.per_gift, 0 )
df['per_bday'] = df.groupby('BirthDayAge').per_gift.cumsum()
df['per_bday'] = np.where( df.per_bday > 30, 30, df.per_bday )
df['granny_pays'] = df.groupby('BirthDayAge').per_bday.diff()
df['granny_pays'] = df.granny_pays.fillna(df.per_bday)
请注意,'per_gift'忽略了30美元的最高补贴,'per_bday'是每个'BirthDayAge'的累积补贴(上限为30美元)。
BirthDayAge DollarsSpent PresentNum per_gift per_bday granny_pays
0 11 25 1 5 5 5
1 11 100 2 80 30 25
2 11 10 3 0 30 0
3 11 50 4 30 30 0
4 12 39 1 19 19 19
5 12 7 2 0 19 0
6 12 32 3 12 30 11
7 12 19 4 0 30 0
8 13 21 1 1 1 1
9 13 27 2 7 8 7