我收到了带有累积数字的数据。是否有一种聪明的方法来减少数据的累积量,所以我每个月都有它,而不是彼此堆叠?
(在此处检查示例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
所需的输出:
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 45 20
01-02-2018 Adomas 90 20
01-02-2018 Thomas 135 35
最好的问候,
Przemyslaw
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每月都不增加,那么您的解决方案就无法正常工作吗?我能以某种方式指定要检查的参数并仅在发生更改时减去吗?
答案 0 :(得分:2)
您可以按销售代表分组并进行逐行差异。然后将数据集合并回去。
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
答案 1 :(得分:1)
基本上使用fprintf(strrep([repmat('%f\t', 1, size(A, 2)) '\n'],'\t\n','\n'), A');
和DataFrame.groupby
。不幸的是,前几行缺少前一行,它们是diff
,需要进行一些混乱的清理工作。可能有更漂亮的方法。
nan
答案 2 :(得分:1)
这是使用shift
的另一种方法。它实际上是减去前一个数字。假定DataFrame已经按照正确的顺序排列(如果不是,请首先使用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
答案 3 :(得分:0)
这是Denziloe回答的不太普遍但更漂亮的版本:
def reverse_cumsum(series):
series_zeroed = pd.concat([pd.Series([0]), series])
return series_zeroed.diff()[1:]
这可以在您的示例中使用,方法是按日期排序,然后在按所需列(在您的情况下为“ SalesRep”)分组之后应用此方法。