Python 仅适用于1列的累积和

Python 仅适用于1列的累积和,python,pandas,cumulative-sum,Python,Pandas,Cumulative Sum,我只想在一个特定的列上应用cumsum,因为我在不同的列中有其他必须保持不变的值 这是我到目前为止的剧本 df.groupby(by=['name','day']).sum().groupby(level=[0]).cumsum() 然而,这个脚本的结果是,我的df中的所有列都将累积。必须累计总和的唯一列是数据 根据要求,以下是一些示例数据: df = pd.DataFrame({'ID': ["880022443344556677787", "880022443344556677782",

我只想在一个特定的列上应用cumsum,因为我在不同的列中有其他必须保持不变的值

这是我到目前为止的剧本

df.groupby(by=['name','day']).sum().groupby(level=[0]).cumsum()
然而,这个脚本的结果是,我的df中的所有列都将累积。必须累计总和的唯一列是
数据

根据要求,以下是一些示例数据:

df = pd.DataFrame({'ID': ["880022443344556677787", "880022443344556677782", "880022443344556677787",
                          "880022443344556677782", "880022443344556677787", "880022443344556677782",
                          "880022443344556677781"],
                   'Month': ["201701", "201701", "201702", "201702", "201703", "201703", "201703"],
                   'Usage': [20, 40, 100, 50, 30, 30, 2000],
                   'Sec': [10, 15, 20, 1, 5, 6, 30]})

                      ID   Month  Sec  Usage
0  880022443344556677787  201701   10     20
1  880022443344556677782  201701   15     40
2  880022443344556677787  201702   20    100
3  880022443344556677782  201702    1     50
4  880022443344556677787  201703    5     30
5  880022443344556677782  201703    6     30
6  880022443344556677781  201703   30   2000
期望输出

                      ID   Month  Sec  Usage
0  880022443344556677787  201701   10     20
1  880022443344556677782  201701   15     40
2  880022443344556677787  201702   20    120
3  880022443344556677782  201702    1     90
4  880022443344556677787  201703    5    150
5  880022443344556677782  201703    6    120
6  880022443344556677781  201703   30   2000
我认为您需要COL,而不需要
cumsum
-我通过
列表理解动态查找它们

cumsum_col = 'Usage'
df1 = df.groupby(by=['ID','Month'], sort=False).sum()
cols = [col for col in df1.columns if col != cumsum_col]

df1 = df1.set_index(cols, append=True).groupby(level=[0]).cumsum().reset_index()
print (df1)
                      ID   Month  Sec  Usage
0  880022443344556677787  201701   10     20
1  880022443344556677782  201701   15     40
2  880022443344556677787  201702   20    120
3  880022443344556677782  201702    1     90
4  880022443344556677787  201703    5    150
5  880022443344556677782  201703    6    120
6  880022443344556677781  201703   30   2000
编辑:

编辑1:

在您的示例中,数据不是聚合的
sum
,因此对数据进行了一些修改(解决方案类似,但与另一个不同):


考虑数据帧
df

df = pd.DataFrame(dict(
        name=list('aaaaaaaabbbbbbbb'),
        day=np.tile(np.arange(2).repeat(4), 2),
        data=np.arange(16)
    ))
首先,通过在
groupby
语句后命名列,对特定列执行
cumsum

其次,您可以使用
join将其添加回数据帧
df

d2 = df.groupby(['name', 'day']).data.sum().groupby(level=0).cumsum()

df.join(d2, on=['name', 'day'], rsuffix='_cum')

    data  day name  data_cum
0      0    0    a         6
1      1    0    a         6
2      2    0    a         6
3      3    0    a         6
4      4    1    a        28
5      5    1    a        28
6      6    1    a        28
7      7    1    a        28
8      8    0    b        38
9      9    0    b        38
10    10    0    b        38
11    11    0    b        38
12    12    1    b        92
13    13    1    b        92
14    14    1    b        92
15    15    1    b        92

您已经可以将累积总和(
'cumsum'
)作为对
df.groupby
的聚合。您需要将其
“cumsum”
作为字符串作为“data”列的聚合函数

df.groupby(['name','day']).agg({'data': 'cumsum'})

这是错误的,因为首先需要aggregate
sum
,然后仅按第一级分组聚合cumsum。是否可以使用cumsum数据添加一个附加列,而不是替换它?不确定发生了什么,但当我将其应用于我的df时,您的第一个方法正在工作,但具有cumsum数据的附加列的新方法返回
NaN
值。你知道发生了什么吗?看来你的真实数据有更多的列,所以需要更改
df1。重置索引(级别=[2,3,4],drop=True)
-每个级别都有更多的列。但我修改了另一个解决方案,等一下。
#join cumsum series to aggregate df1
df3 = df1.join(s, rsuffix='_cumsum').reset_index()
print (df3)
                      ID   Month  Sec  Usage  Usage_cumsum
0  880022443344556677781  201703   30   2000          2000
1  880022443344556677782  201701   21     70            70
2  880022443344556677782  201702    1     50           120
3  880022443344556677787  201701   30    120           120
4  880022443344556677787  201703    5     30           150
df = pd.DataFrame(dict(
        name=list('aaaaaaaabbbbbbbb'),
        day=np.tile(np.arange(2).repeat(4), 2),
        data=np.arange(16)
    ))
d2 = df.groupby(['name', 'day']).data.sum().groupby(level=0).cumsum()

df.join(d2, on=['name', 'day'], rsuffix='_cum')

    data  day name  data_cum
0      0    0    a         6
1      1    0    a         6
2      2    0    a         6
3      3    0    a         6
4      4    1    a        28
5      5    1    a        28
6      6    1    a        28
7      7    1    a        28
8      8    0    b        38
9      9    0    b        38
10    10    0    b        38
11    11    0    b        38
12    12    1    b        92
13    13    1    b        92
14    14    1    b        92
15    15    1    b        92
df.groupby(['name','day']).agg({'data': 'cumsum'})