熊猫:取消累积(如累积总和)

2024-06-24 12:31:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经收到了累积数字的数据。有没有一种聪明的方法来消除数据的累积,这样我就可以逐月把数据存储起来,而不是把它们叠加在一起?在

(请在此处查看示例xlsx:https://docs.google.com/spreadsheets/d/1yELrJdZmi3CFJccYSi5U6GGDW-Awp5spHDnsDyshBe0/edit?usp=sharing。)

输入示例:

Date    SalesRep    itemA   itemB
01-01-2018  Jakob   5       10
01-01-2018  Adomas  10      20
01-01-2018  Thomas  15      30
01-02-2018  Jakob   50      30
01-02-2018  Adomas  100     40
01-02-2018  Thomas  150     65

期望输出:

^{pr2}$

谨致问候

普氏定律

p.S.更新

如果数据不是每个月都在增加,那情况如何?在

输入示例:

Date    SalesRep    itemA   itemB
01-01-2018  Jakob   5       10
01-01-2018  Adomas  10      20
01-01-2018  Thomas  15      30
**01-02-2018    Jakob   50      30**
01-02-2018  Adomas  100     40
01-02-2018  Thomas  150     65
**01-03-2018    Jakob   50      30**
01-03-2018  Adomas  102     60
01-03-2018  Thomas  155     75

如果Jakob没有每月递增,那么您的解决方案就不起作用了?我能不能指定一些参数来检查它,只有在有变化时才进行减法?在


Tags: 数据方法https示例docsdategooglethomas
3条回答

您可以按销售代表分组,并按行排序。然后将数据集合并到一起。在

import pandas as pd

df = pd.DataFrame({
    'Date': ['01-01-2018', '01-01-2018', '01-01-2018', '01-02-2018', '01-02-2018', '01-02-2018'],
    'SalesRep': ['Jakob', 'Adomas', 'Thomas', 'Jakob', 'Adomas', 'Thomas',],
    'itemA': [5, 10, 15, 50, 100, 150],
    'itemB': [10, 20, 30, 30, 40, 65]})

df_diff = df.groupby('SalesRep').diff().fillna(0).astype(int)
df.loc[:, ['itemA', 'itemB']] = df_diff.where(df_diff, df.loc[:, ['itemA', 'itemB']])

df
# returns:
         Date SalesRep  itemA  itemB
0  01-01-2018    Jakob      5     10
1  01-01-2018   Adomas     10     20
2  01-01-2018   Thomas     15     30
3  01-02-2018    Jakob     45     20
4  01-02-2018   Adomas     90     20
5  01-02-2018   Thomas    135     35

这里有一种使用shift的不同方法。它实质上是减去前面的数字。它假定数据帧已经处于正确的顺序(如果不是,请先使用DataFrame.sort_values)。我认为这是更好的,因为它提供了一个到位的一个班轮。在

df = pd.DataFrame(
    data=[
        ['01-01-2018', 'Jakob', 5, 10],
        ['01-01-2018', 'Adomas', 10, 20],
        ['01-01-2018', 'Thomas', 15, 30],
        ['01-02-2018', 'Jakob', 50, 30],
        ['01-02-2018', 'Adomas', 100, 40],
        ['01-02-2018', 'Thomas', 150, 65],
        ['01-03-2018', 'Jakob', 60, 30],
        ['01-03-2018', 'Adomas', 120, 45],
        ['01-03-2018', 'Thomas', 200, 75]
    ],
    columns=['Date', 'Sales rep', 'item A', 'item B']
)

group_by_columns = ['Sales rep']
cum_columns = ['item A', 'item B']

df[cum_columns] -= df.groupby(group_by_columns)[cum_columns].shift(1).fillna(0)

print(df)
Out:
         Date Sales rep  item A  item B
0  01-01-2018     Jakob     5.0    10.0
1  01-01-2018    Adomas    10.0    20.0
2  01-01-2018    Thomas    15.0    30.0
3  01-02-2018     Jakob    45.0    20.0
4  01-02-2018    Adomas    90.0    20.0
5  01-02-2018    Thomas   135.0    35.0
6  01-03-2018     Jakob    10.0     0.0
7  01-03-2018    Adomas    20.0     5.0
8  01-03-2018    Thomas    50.0    10.0

基本上使用DataFrame.groupby和{}。不幸的是,第一行缺少用于区别的前一行,是nan,这需要一些混乱的清理。也许还有更漂亮的方法。在

df = pd.DataFrame(
    data=[
        ['01-01-2018', 'Jakob', 5, 10],
        ['01-01-2018', 'Adomas', 10, 20],
        ['01-01-2018', 'Thomas', 15, 30],
        ['01-02-2018', 'Jakob', 50, 30],
        ['01-02-2018', 'Adomas', 100, 40],
        ['01-02-2018', 'Thomas', 150, 65],
        ['01-03-2018', 'Jakob', 60, 30],
        ['01-03-2018', 'Adomas', 120, 45],
        ['01-03-2018', 'Thomas', 200, 75]
    ],
    columns=['Date', 'Sales rep', 'item A', 'item B']
)

cum_columns = ['item A', 'item B']

result = df.merge(
    df.groupby('Sales rep')[cum_columns].diff(),
    left_index=True, right_index=True, suffixes=['', '_uncum']
).fillna({'{}_uncum'.format(cum_column): df[cum_column] for cum_column in cum_columns})

print(result)
Out:
         Date Sales rep  item A  item B  item A_uncum  item B_uncum
0  01-01-2018     Jakob       5      10           5.0          10.0
1  01-01-2018    Adomas      10      20          10.0          20.0
2  01-01-2018    Thomas      15      30          15.0          30.0
3  01-02-2018     Jakob      50      30          45.0          20.0
4  01-02-2018    Adomas     100      40          90.0          20.0
5  01-02-2018    Thomas     150      65         135.0          35.0
6  01-03-2018     Jakob      60      30          10.0           0.0
7  01-03-2018    Adomas     120      45          20.0           5.0
8  01-03-2018    Thomas     200      75          50.0          10.0

相关问题 更多 >