1

我有一个 df 看起来像

A    B
1.2  1
1.3  1
1.1  1
1.0  0
1.0  0
1.5  1
1.6  1
0.7  1
1.1  0

有没有什么函数或方法可以逐个计算cumsum,我的意思是对于每个连续的B值1,计算cumsum,在上面的例子中应该是

A    B    C
1.2  1    1.2
1.3  1    2.5
1.1  1    3.6
1.0  0    0
1.0  0    0
1.5  1    1.5
1.6  1    3.1
0.7  1    3.8
1.1  0    0

非常感谢,

4

3 回答 3

2
from io import StringIO
import pandas as pd
import numpy as np

text = """a  b
1.2  1
1.3  1
1.1  1
1.0  0
1.0  0
1.5  1
1.6  1
0.7  1
1.1  0"""

df = pd.read_csv(StringIO(text), delim_whitespace=True)

c = df["a"].cumsum()
mask = ~df["b"].astype(bool)
s = pd.Series(np.nan, index=df.index)
s[mask] = c[mask]
c -= s.ffill().fillna(0)
print(c)

输出:

0    1.2
1    2.5
2    3.6
3    0.0
4    0.0
5    1.5
6    3.1
7    3.8
8    0.0
dtype: float64
于 2013-09-11T06:41:27.693 回答
2

另一种方法(可能更通用)是对 B 中的连续条目进行分组。

首先我们枚举组:

In [11]: (df.B != df.B.shift())
Out[11]: 
0     True
1    False
2    False
3     True
4    False
5     True
6    False
7    False
8     True
Name: B, dtype: bool

In [12]: enumerate_B_changes = (df.B != df.B.shift()).astype(int).cumsum()

In [13]: enumerate_B_changes
Out[13]: 
0    1
1    1
2    1
3    2
4    2
5    3
6    3
7    3
8    4
dtype: int64

然后我们可以按这个 Series 和 cumsum 分组:

In [14]: df.groupby(enumerate_B_changes)['A'].cumsum()
Out[14]: 
0    1.2
1    2.5
2    3.6
3    1.0
4    2.0
5    1.5
6    3.1
7    3.8
8    1.1
dtype: float64

但是,在这种情况下,我们必须乘以 df['B'] 以说明 B 列中的 0。

In [15]: df.groupby(enumerate_B_changes)['A'].cumsum() * df['B']
Out[15]: 
0    1.2
1    2.5
2    3.6
3    0.0
4    0.0
5    1.5
6    3.1
7    3.8
8    0.0
dtype: float64

如果我们想要对整数既不是 0 也不是 1 进行不同的操作,我们可以在这里做一些不同的事情。

于 2013-09-11T09:47:36.907 回答
1

我不是非常精通 numpy,但是下面的代码应该会有所帮助。

它通过并且如果b是 1 继续添加到累积和,否则它重置它。

df = [
(1.2, 1),
(1.3, 1),
(1.1, 1),
(1.0, 0),
(1.0, 0),
(1.5, 1),
(1.6, 1),
(0.7, 1),
(1.1, 0)]

c=[]
cumsum=0
for a,b in df:
    if b == 1:
        cumsum +=a
        c.append(cumsum)
    else:
        cumsum = 0
        c.append(0)
print c

它输出(带有舍入问题,这在 numpy 中不应该发生):

[1.2, 2.5, 3.6000000000000001, 0, 0, 1.5, 3.1000000000000001, 3.7999999999999998, 0]
于 2013-09-11T05:38:29.313 回答