我要累加一列,但求和之前必须将每一行的值与另一列的值进行检查,如果另一列的值较小,则该值将累加起来,而不是第一列的前一行。考虑以下数据帧:
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,但是如果Y小于上一行中的X,它将累加而不是X。例如,X的第二行的累加结果为1,但是第二秒为0 Y的行小于1,我们将其替换。然后,第三行的总和将为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
我希望有人可以提出一种更有效的方法。
答案 0 :(得分:0)
由于您的“专业累积”取决于先前的结果, 您无法使用实际的 cumsum 函数。
相反,您应该使用“带有内存”功能(请记住 先前返回的值),并在下一次调用中使用(用于 下一行)。
行 0 是一种特殊情况。由于对于第 0 行,没有以前的行 Z 列的值,即使在您的代码中,您也将结果留给了 第一行为 0 ,所以我在函数中的操作相同(见下文)。
其他行是根据您的算法计算的。
要计算您的“专业累积”,请定义以下函数:
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