Python Pandas-如果列中的值满足条件,则对前面的行求和

Python Pandas-如果列中的值满足条件,则对前面的行求和,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个以下类型的数据帧。除了最后一列“之前的总积分P1”,我有所有的列,我希望创建: 数据按“日期”列排序 现在我要创建的列是上面显示的“Total_Previous_Points_P1”列 创建它的方法: 对于每一行,检查日期(称之为日期)和P1_id(称之为id_VAL) 现在,对于DATE_VAL之前的所有行,其中P1 id==id_VAL,求和前面的几点 将此总和放入当前行的最后一列 有没有一种快速的熊猫蟒蛇式的方法可以做到这一点?我的数据集非常大 谢谢大家! 试试看: df['T

我有一个以下类型的数据帧。除了最后一列“之前的总积分P1”,我有所有的列,我希望创建:

数据按“日期”列排序

现在我要创建的列是上面显示的“Total_Previous_Points_P1”列

创建它的方法:

  • 对于每一行,检查日期(称之为日期)和P1_id(称之为id_VAL)
  • 现在,对于DATE_VAL之前的所有行,其中P1 id==id_VAL,求和前面的几点
  • 将此总和放入当前行的最后一列
有没有一种快速的熊猫蟒蛇式的方法可以做到这一点?我的数据集非常大

谢谢大家!

试试看:

df['Total_Previous_Points_P1'] = df.groupby(['P1_id'])['Points_P1'].cumsum()

它的工作原理

首先,它使用
P1\u id
功能对数据进行分组

然后,它访问分组数据帧上的
Points\u P1
值,并应用累积求和函数
cumsum()
,该函数返回每个组当前行之前的点数总和

SIA的解决方案计算点之和,包括 点P1的当前值,而要求为总和 上一个点(对于之前的所有行)

假设每组中的日期都是唯一的(在您的样本中是唯一的), 正确的泛达索尼克解决方案应包括以下步骤:

  • 按日期排序
  • 按P1_id分组,然后针对每个组:
  • 在P1列中取点
  • 计算累积和
  • 减去点_P1的当前值
因此,整个代码应该是:

df['Total_Previous_Points_P1'] = df.sort_values('Date')\
    .groupby(['P1_id']).Points_P1.cumsum() - df.Points_P1
编辑 如果日期不唯一(在具有某些P1_id的行组中),则 更复杂的是,在这样的源数据帧上可以显示什么:

        Date  Points_P1  P1_id
0 2016-11-09          5    100
1 2016-11-09          3    100
2 2015-10-08          5    100
3 2019-09-20         10  10000
4 2019-09-21          7    100
5 2019-07-10         12  10000
6 2019-12-10         12  10000
请注意,对于P1_id,2016-11-09有两行

在这种情况下,从计算前几点的“组”和开始, 对于每个P1_id和日期:

结果是:

P1_id  Date      
100    2015-10-08     0
       2016-11-09     5
       2019-09-21    13
10000  2019-07-10     0
       2019-09-20    12
       2019-12-10    22
Name: Total_Previous_Points_P1, dtype: int64
然后在P1_id和日期上将df与sumPrev合并(在索引上的sumPrev中):

为了显示结果,将df也按['P1_id','Date']进行排序更具指导意义:

如你所见:

  • 每个P1_id的第一个总和为0(以前的日期没有积分)
  • 例如,对于日期==2016-11-09的两行 分数为5分(日期==2015-10-08的行中)

谢谢,这几乎可以正常工作,但我遇到以下错误:
“试图在数据帧切片的副本上设置一个值。尝试使用.loc[row\u indexer,col\u indexer]=value代替'
。相反,如果我创建一个新变量,
newcol=df.groupby(['P1\u id'])['Points\u P1'].cumsum()
,则不会返回错误。如果我以后尝试使用
df['Total\u Previous\u Points\u P1']=newcol
,我会遇到类似的问题
sumPrev = df.groupby(['P1_id', 'Date']).Points_P1.sum()\
    .groupby(level=0).apply(lambda gr: gr.shift(fill_value=0).cumsum())\
    .rename('Total_Previous_Points_P1')
P1_id  Date      
100    2015-10-08     0
       2016-11-09     5
       2019-09-21    13
10000  2019-07-10     0
       2019-09-20    12
       2019-12-10    22
Name: Total_Previous_Points_P1, dtype: int64
df = pd.merge(df, sumPrev, left_on=['P1_id', 'Date'], right_index=True)
        Date  Points_P1  P1_id  Total_Previous_Points_P1
2 2015-10-08          5    100                         0
0 2016-11-09          5    100                         5
1 2016-11-09          3    100                         5
4 2019-09-21          7    100                        13
5 2019-07-10         12  10000                         0
3 2019-09-20         10  10000                        12
6 2019-12-10         12  10000                        22