[英]Pandas: Conditional cumsum based on previous row value of another column
我想对一列求和,但求和前每一行的值必须与另一列的值进行检查,如果另一列的值较小,则该值加起来而不是第一列的前一行。 考虑这个 dataframe:
df = pd.DataFrame({'X': [0,1,0,1,1,0,0,0,0,1,1,1,0,1], 'Y': [0, 0, 1, 1, 1, 2, 3, 4, 4, 4, 4, 4, 5, 5]})
X Y
0 0 0
1 1 0
2 0 1
3 1 1
4 1 1
5 0 2
6 0 3
7 0 4
8 0 4
9 1 4
10 1 4
11 1 4
12 0 5
13 1 5
现在,我想对 X 进行 cumsum,但是如果 Y 小于上一行中的 X,它将相加而不是 X。例如,X 的第二行的 cumsum 结果为 1,但因为 Y 的第二行中的 0小于1,我们替换它。 那么第三行的 cumsum 将是 0 而不是 1。我使用“for循环”编写了如下代码,但对于大型数据集它根本没有效率:
df['Z'] = 0
for index in range(1,len(df)):
df.loc[index, 'Z'] = min(df.loc[index, 'X']+df.loc[index-1, 'Z'], df.loc[index, 'Y'])
Z 的预期结果是:
X Y Z
0 0 0 0
1 1 0 0
2 0 1 0
3 1 1 1
4 1 1 1
5 0 2 1
6 0 3 1
7 0 4 1
8 0 4 1
9 1 4 2
10 1 4 3
11 1 4 4
12 0 5 4
13 1 5 5
我会很感激有人可以提出一种更有效的方法。
由于您的“专业 cumsum”的结果取决于先前的结果,因此您不能使用实际的cumsum function。
相反,您应该使用 function “带内存”(记住上一个返回值)并在下一次调用中使用它(用于下一行)。
第0行在这里是一个特例。 由于第0行没有Z列的先前值,即使在您的代码中您将第一行的结果保留为0 ,所以我在 function 中做了同样的事情(见下文)。
其他行根据您的算法计算。
要计算您的“专业 cumsum”,请定义以下 function:
def myCumSum(row):
if row.name == 0:
myCumSum.prev = 0
else:
myCumSum.prev = min(row.X + myCumSum.prev, row.Y)
return myCumSum.prev
关于row.name的一点解释:它实际上是当前行的索引,我的解决方案依赖于源 DataFrame 具有默认索引的事实,即从0开始的连续数字。
然后将其应用于每一行并将结果保存在新列( Z )中:
df['Z'] = df.apply(myCumSum, axis=1)
结果是:
X Y Z
0 0 0 0
1 1 0 0
2 0 1 0
3 1 1 1
4 1 1 1
5 0 2 1
6 0 3 1
7 0 4 1
8 0 4 1
9 1 4 2
10 1 4 3
11 1 4 4
12 0 5 4
13 1 5 5
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.