通过汇总在熊猫组上使用自定义功能

时间:2020-01-16 15:10:48

标签: python pandas dataframe

我有一个这样的数据框,

>>> data = {
    'year':[2019, 2020, 2020, 2019, 2020, 2019],
    'provider':['X', 'X', 'Y', 'Z', 'Z', 'T'],
    'price':[100, 122, 0, 150, 120, 80],
    'count':[20, 15, 24, 16, 24, 10]
}
>>> df = pd.DataFrame(data)
>>> df
   year provider  price  count
0  2019        X    100     20
1  2020        X    122     15
2  2020        Y      0     24
3  2019        Z    150     16
4  2020        Z    120     24
5  2019        T     80     10

这是预期的输出:

  provider  price_rate  count_rate
0        X        0.22       -0.25
1        Z       -0.20        0.50

我想对提供商进行价格分组并找到价格,计算出2019年与2020年之间的差异。 如果在2020年或2019年没有价格或数量记录,则不希望看到相关的提供商。

2 个答案:

答案 0 :(得分:3)

假设每个提供者总是只有1或2行,我们可以首先在sort_valuesyear,以确保20192020之前。

然后我们在提供者上groupby,在divideprice的行count上减去1。

df = df.sort_values('year')
grp = (
    df.groupby('provider')
      .apply(lambda x: x[['price', 'count']].div(x[['price', 'count']].shift()).sub(1))
)

dfnew = df[['provider']].join(grp).dropna()

  provider  price  count
1        X   0.22  -0.25
4        Z  -0.20   0.50

或仅矢量化方法:

dfnew = df[df['provider'].duplicated(keep=False)].sort_values(['provider', 'year'])
dfnew[['price', 'count']] = (
    dfnew[['price', 'count']].div(dfnew[['price', 'count']].shift()).sub(1)
)

dfnew = dfnew[dfnew['provider'].eq(dfnew['provider'].shift())].drop('year', axis=1)

  provider  price  count
1        X   0.22  -0.25
4        Z  -0.20   0.50

答案 1 :(得分:3)

您可以尝试:

final = (df.set_index(['provider','year']).groupby(level=0)
      .pct_change().dropna().droplevel(1).add_suffix('_count').reset_index())

  provider  price_rate  count_rate
0        X        0.22       -0.25
1        Z       -0.20        0.50
相关问题