我正在使用熊猫上的数据框,并且试图将不同行的值求和到一个新列。这必须基于上一个日期(准确地说是当前月份-1)。
我有这样的东西:
Period Value
2015-01 1
2015-09 2
2015-10 1
2015-11 3
2015-12 1
我想创建一个新列,其中包含当前'Period'和'Period'-1month)(如果存在)之和。示例:
Period Value Result
2015-01 1 1
2015-09 2 2
2015-10 1 3
2015-11 3 4
2015-12 1 4
我试图将lambda函数与类似的东西一起使用:
df['Result'] = df.apply(lambda x: df.loc[(df.Period <= x.Period) &
(x.Period >= df.Period-1),
['Value']].sum(), axis=1)
它是基于其他答案的,但是如果这是最好的方法以及如何使其成功运行,我会感到有点困惑(它没有给出任何python错误消息,但没有给出我的预期输出)。
更新
我在一个包含三列的简单示例中测试@taras答案:
Account Period Value
15035 2015-01 1
15035 2015-09 1
15035 2015-10 1
预期结果将是:
Account Period Value
15035 2015-01 1
15035 2015-09 1
15035 2015-10 2
但是我得到了:
Account Period Value
15035 2015-01 1
15035 2015-09 2
15035 2015-10 2
检查时
print(df.loc[df.index - 1, 'Value'].fillna(0).values)
我得到[0. 1. 1。](应该是[0. 0. 1.])。通过查看
print(df.loc[df.index - 1, 'Period'].fillna(0).values)
我正在获取[0 Period('2015-01','M')Period('2015-09','M')](看起来索引从上一行获取值,并且不是上个月)。
我做错什么了吗?
答案 0 :(得分:2)
您可以使用以下方式计算上个月的行索引:
idx = df.index - pd.DateOffset(months=1)
,然后将其添加到您的Value
列
df.loc[idx, 'Value'].fillna(0).values + df['Value']
结果
Period
2015-01-01 1.0
2015-09-01 2.0
2015-10-01 3.0
2015-11-01 4.0
2015-12-01 4.0
Name: Value, dtype: float64
更新:由于您使用pd.PeriodIndex
而不是df.DatetimeIndex
,因此idx
的计算方式非常简单:
idx = df.index - 1
因为您的期限是1个月。
因此,总结起来,整个事情可以用一个非常简单的表达式表示:
df.loc[df.index - 1, 'Value'].fillna(0).values + df['Value']
答案 1 :(得分:1)
您可以加入一个辅助列来管理输入的字符串转换:
import pandas as pd
from datetime import datetime
df['prev'] = (df.Period.apply(lambda x: x.to_timestamp()) - pd.DateOffset(months=1)
aux = df.merge(df, how='left', left_on = 'prev', right_on = 'Period')
df['sum'] = aux.Value_x + aux.Value_y
df= df.drop('prev',axis=1)