如何在 pandas 中查找相同号码和名称的增量?

How to find delta for same number and name in pandas?

我有以下数据框,我需要减去并找到下一个四分之一和当前四分之一加上下一个四分之一和当前四分之一之间的增量。

输入数据:

Number Name Year Quater value
1      an   2018 1      2.5
2      bn   2018 1      1.5
1      an   2018 2      3.5
2      bn   2018 2      4.5
1      an   2018 3      4.5
1      an   2018 4      2.5
2      bn   2018 4      1.5
1      an   2019 1      5.5
2      bn   2019 1      1.5

输出:d_1 是相同数字和名称的下一个四分之一和当前四分之一之间的差异,而 d_2 是相同数字和名称的下一个四分之一和当前四分之一之间的差异。

Number Name Year Quater value d_1 d_2
1      an   2018 1      2.5   1   2
2      bn   2018 1      1.5   3   
1      an   2018 2      3.5   1   -1
2      bn   2018 2      4.5       -3
1      an   2018 3      4.5   -2  1
1      an   2018 4      2.5   3
2      bn   2018 4      1.5   0
1      an   2019 1      5.5  
2      bn   2019 1      1.5

首先,确保数据排序正确:

df = df.sort_values(by=['Year', 'Quater'])

然后用groupby and diff计算行间的差异:

df['d_1'] = df.groupby(['Number', 'Name'])['value'].diff(periods=-1) * -1
df['d_2'] = df.groupby(['Number', 'Name'])['value'].diff(periods=-2) * -1
df = df.fillna(0.0)

结果:

Number  Name  Year  Quater  value   d_1   d_2
     1    an  2018       1    2.5   1.0   2.0
     2    bn  2018       1    1.5   3.0  -0.0
     1    an  2018       2    3.5   1.0  -1.0
     2    bn  2018       2    4.5  -3.0  -3.0
     1    an  2018       3    4.5  -2.0   1.0
     1    an  2018       4    2.5   3.0   0.0
     2    bn  2018       4    1.5  -0.0   0.0
     1    an  2019       1    5.5   0.0   0.0
     2    bn  2019       1    1.5   0.0   0.0

编辑:

如果还应考虑缺失值,最好的方法是 resample 数据框首先添加任何缺失的行。

首先,添加一个新列date并对数据帧重新采样:

df['date'] = pd.to_datetime(df['Year'].astype(str) + 'Q' + df['Quater'].astype(str))
df = df.set_index('date').groupby(['Number', 'Name']).resample('Q').first().drop(['Name', 'Number'], axis=1).reset_index()

现在我们有:

Number  Name          date  Year  Quater  value
     1    an    2018-03-31  2018     1.0    2.5
     1    an    2018-06-30  2018     2.0    3.5
     1    an    2018-09-30  2018     3.0    4.5
     1    an    2018-12-31  2018     4.0    2.5
     1    an    2019-03-31  2019     1.0    5.5
     2    bn    2018-03-31  2018     1.0    1.5
     2    bn    2018-06-30  2018     2.0    4.5
     2    bn    2018-09-30   NaN     NaN    NaN
     2    bn    2018-12-31  2018     4.0    1.5
     2    bn    2019-03-31  2019     1.0    1.5

现在应用与上面相同的 groupbydiff,并删除额外的行,date 列并对结果进行排序:

df['d_1'] = df.groupby(['Number', 'Name'])['value'].diff(periods=-1) * -1
df['d_2'] = df.groupby(['Number', 'Name'])['value'].diff(periods=-2) * -1
df.dropna(subset=['Year']).fillna(0.0).sort_values(by=['Year', 'Quater']).drop('date', axis=1)

如果您希望保留 NaN,可以跳过 fillna