Python 根据日期对不同列的值求和

Python 根据日期对不同列的值求和,python,pandas,Python,Pandas,我正在使用pandas上的dataframe,并尝试将不同行的值求和到一个新列。这必须基于上一个日期(准确地说是当前月份-1) 我有这样的想法: Period Value 2015-01 1 2015-09 2 2015-10 1 2015-11 3 2015-12 1 我想创建一个新列,其中包含当前“期间”和(“期间”-1个月)的“值”之和(如果存在)。例如: Period Value Result 2015-01 1 1 2015-09 2 2 2015-10 1

我正在使用pandas上的dataframe,并尝试将不同行的值求和到一个新列。这必须基于上一个日期(准确地说是当前月份-1)

我有这样的想法:

Period  Value
2015-01 1
2015-09 2
2015-10 1
2015-11 3
2015-12 1
我想创建一个新列,其中包含当前“期间”和(“期间”-1个月)的“值”之和(如果存在)。例如:

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)
预期结果将是:

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')](看起来索引是从上一行得到的值,而不是上一个月)


我做错什么了吗?

您可以使用

idx = df.index - pd.DateOffset(months=1)
然后只需将其添加到
列中即可

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
因为你的月经是一个月

总之,整个事情可以用一个非常简单的表达式来表达:

df.loc[df.index - 1, 'Value'].fillna(0).values + df['Value']

您可以使用

idx = df.index - pd.DateOffset(months=1)
然后只需将其添加到
列中即可

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
因为你的月经是一个月

总之,整个事情可以用一个非常简单的表达式来表达:

df.loc[df.index - 1, 'Value'].fillna(0).values + df['Value']

您可以在管理输入字符串转换的辅助列上联接:

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) 

您可以在管理输入字符串转换的辅助列上联接:

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) 


什么类型的周期?string?Period是一个PeriodIndex,通过使用列上的函数dt.to_Period(“M”)获得(它以前是一个日期时间)。Period的类型是什么?string?Period是一个PeriodIndex,通过在列上使用函数dt.to_Period(“M”)获得(以前是datetime)。Period列是一个PeriodIndex,通过在列上使用函数dt.to_Period(“M”)获得(以前是datetime)。是否有使用此类型的解决方法?哦,在你的回答中,似乎有一个“)“在end@LuizFGonçalves,我已经更新了答案,因此它正确地处理了
PeriodIndex
@taras,我会试试看它是否还有其他问题。Thanks@taras我在这里进行测试,您的PeriodIndex解决方案似乎没有考虑上个月(当前-1),而是考虑上一行。第二行是添加第一行的值,但它不应该(因为2015-09应该与2015-08相关,而不是2015-01)。我的完整数据在周期前有一列,这对问题本身并不重要(这是一个在所有行中重复的值),但我担心这可能是您的解决方案不适用于我的原因。该列有问题吗?Period列是一个PeriodIndex,通过使用列上的函数dt.to_Period(“M”)获得(以前是datetime)。是否有使用此类型的解决方法?哦,在你的回答中,它似乎有一个“)”在end@LuizFGonçalves,我已经更新了答案,因此它正确地处理了
PeriodIndex
@taras,我会试试看它是否还有其他问题。Thanks@taras我在这里进行测试,您的PeriodIndex解决方案似乎没有考虑上个月(当前-1),而是考虑上一行。第二行是添加第一行的值,但它不应该(因为2015-09应该与2015-08相关,而不是2015-01)。我的完整数据在周期前有一列,这对问题本身并不重要(这是一个在所有行中重复的值),但我担心这可能是您的解决方案不适用于我的原因。这个列有问题吗?我认为您的解决方案会起作用,但我必须调整代码的某些部分,使其能够正确地使用PeriodIndex(例如,pd.DateOffset(months=1)不起作用)。我现在正在做,然后我会告诉你结果。谢谢如果你有一个PeriodIndex,你可以替换Period.apply to Period.to_timestamp()直接:)我将lambda函数改为(lambda x:x-1),它似乎可以与PeriodIndex一起工作。我正在投票表决,等待塔拉斯的答案决定最佳解决方案。非常感谢您的帮助。我认为您的解决方案会起作用,但我必须调整代码的某些部分,使其能够正确地使用PeriodIndex(例如,pd.DateOffset(months=1)不起作用)。我现在正在做,然后我会告诉你结果。谢谢如果你有一个PeriodIndex,你可以替换Period.apply to Period.to_timestamp()直接:)我将lambda函数改为(lambda x:x-1),它似乎可以与PeriodIndex一起工作。我正在投票表决,等待塔拉斯的答案决定最佳解决方案。非常感谢你的帮助。