根据条件计算行的总和

时间:2021-06-15 13:02:43

标签: python python-3.x pandas python-2.7

我有一个 df

data = [[1, 10], [1, 5], [1, 4], [0, 3], [0, 3], [1, 2], [1, 1], [1, 5], [2, 8], [4, 9]]
df = pd.DataFrame(data, columns = ['no', 'count'])

将值打印为,

no  count
1    10   
1    5
1    4
0    3
0    3
1    2
1    1
1    5
2    8
4    9 
  • 我想在“no”变为 1 时获得第一个“计数”(视为值 1)
  • 当数字为“非 1”时,获取该“计数”(视为值 2)
  • 减去 value2 - value1
  • 当“no”再次变为 1 时开始下一个值。
  • 最后,计算总和

预期输出: (10-3) = 7 和 (2-8) = -6

7
-6

总和是,

1

2 个答案:

答案 0 :(得分:2)

这是一种方法:

>>> vals = df.groupby(df.no.eq(1).diff().ne(0).cumsum())["count"].first()
>>> result = (vals * (-1) ** np.arange(len(vals))).sum()
>>> result
1

我们首先将连续的组分组为 1 或不为 1 并取其中的第一个值。然后为了给值加上交替符号,我们使用 (-1)0..N-1 的幂。然后我们对乘法求和。

vals 顺便说一下:

1    10
2     3
3     2
4     8

不乘以 -1 的幂的替代方法:

vals = df.groupby(df.no.eq(1).diff().ne(0).cumsum())["count"].first().to_numpy()

result = (vals[::2] - vals[1::2]).sum()

我们从偶数索引值中减去奇数索引值。


另一种基于 itertools.groupby 的替代方案,具有 1 次传递数据:

from itertools import groupby
from operator import itemgetter

iterable = enumerate(groupby(zip(df["no"].eq(1), df["count"]), key=itemgetter(0)))

result = sum((1-2*(j&1)) * next(gr)[1] for j, (_, gr) in iterable)

使用枚举和 j 的奇偶校验即时确定符号。但不那么可读。

答案 1 :(得分:2)

groupby df['no'].eq(1) (m) 和 m.ne(m.shift()).cumsum() 的另一种方法:

m = df['no'].eq(1)
g = (
    df.groupby([m, m.ne(m.shift()).cumsum()])['count'].first()
)
no     no
False  2      3
       4      8
True   1     10
       3      2
Name: count, dtype: int64

然后从 True no 中减去 False no:

g.loc[True].values - g.loc[False].values
[ 7 -6]

sum

(g.loc[True].values - g.loc[False].values).sum()
1
相关问题