我试图通过引用三列将lambda函数应用于数据帧。我想根据以下逻辑更新其中一列Cumulative Total
:
如果它在第一行,那么Cumulative Total
应该等于Total
中的值。
如果它不是第一行,则应用以下引用前一行的公式:
x.shift()['Cumulative Total']
- (x.shift()['Total'] * (x.shift()['Annualized Rate'] / 1200))
我希望Cumulative Total
列看起来像这样:
Total Annualized Rate Cumulative Total
869 11.04718067 869
868 5.529953917 861
871 8.266360505 857
873 6.872852234 851
873 8.24742268 846
874 9.610983982 840
870 5.517241379 833
871 8.266360505 829
868 2.764976959 823
让我失望的是我如何判断我是否在第一行。这听起来相当微不足道,但我对熊猫来说非常新鲜,而且我完全被难倒了。 iloc
似乎无法正常工作,因为它似乎只用于抓取给定索引的一行。
目前代码如下:
df['Cumulative Total'] = df.apply(lambda x: x['Total'] if x.iloc[0] else x.shift()['Cumulative Total']-(x.shift()['Total']*(x.shift()['Annualized Rate']/1200)),axis=1)
声明if x.iloc[0]
是错误的。关于我如何确定它是否是第一行的任何想法?
修改:谢谢大家的回答。亚历山大的答案是正确的,但我注意到结果偏离了预期的结果。使用的数据框越大,这些差异就越明显。
亚历山大 - 您可以通过编辑答案来解决这个问题吗?使用vanilla Python,我已经得到了下面的结果。这些差异在很大程度上是微不足道的,但如上所述,使用更大的数据集可能会更加明显。
total=(869,868,871,873,873,874,870,871,868)
rate=(11.047181,5.529954,8.266361,6.872852,8.247423,9.610984,5.517241,8.266361,2.764977)
def f(total,rate):
cum = []
for i in range(len(total)):
if i == 0:
cum.append(total[i])
else:
cum.append(float(cum[i-1])-(float(total[i-1])*(rate[i-1]/1200.0)))
return cum
f(total, rate)
返回:
869
860.9999997591667
856.9999996991667
850.99999934
845.9999995100001
839.9999992775
832.9999992641667
828.9999995391668
822.9999991800001
答案 0 :(得分:2)
也许这个?
df = df.assign(
Cumulative_Total=df['Total'].iat[0]
- ((df['Total'] * df['Annualized Rate'].div(1200))
.shift()
.fillna(0)
.cumsum())
)
>>> df
Total Annualized Rate Cumulative_Total
0 869 11.047181 869
1 868 5.529954 861
2 871 8.266361 857
3 873 6.872852 851
4 873 8.247423 846
5 874 9.610984 840
6 870 5.517241 833
7 871 8.266361 829
8 868 2.764977 823
答案 1 :(得分:0)
这会有用吗?在此解决方案中,我使用x.name
来获取行索引。
df['Cumulative Total'] = df.apply(lambda x: x['Total'] if x.name == 0 else x.shift()['Cumulative Total']-(x.shift()['Total']*(x.shift()['Annualized Rate']/1200)),axis=1)