如何将groupby().transform()转换为特定的行值,而不是像min()这样的函数结果?

2024-04-29 14:21:36 发布

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

我有一个熊猫数据帧df1,看起来像这样:

输入:

Shop               Item  Card   Price
Butcher            A     AMEX   1.5
Butcher            A     VISA   0.9
Baker              B     AMEX   2.5
Baker              B     VISA   3.5
Candlestick maker  C     AMEX   1.5
Candlestick maker  C     VISA   1.5

我知道df1.groupby(["Shop"])['Price'].transform(min)会给我一列min()df1.Price

不过,我想转换为通过VISA支付达到的Price,以便将折扣与Card中的其他价值进行比较。如您所见,这并不总是min(),也不总是max()。你知道吗

所需输出:

Shop              Item Card  Price  Price with VISA
Butcher           A    AMEX  1.5    0.9
Butcher           A    VISA  0.9    0.9
Baker             B    AMEX  2.5    3.5
Baker             B    VISA  3.5    3.5
Candlestick maker C    AMEX  1.5    1.5
Candlestick maker C    VISA  1.5    1.5

我目前的解决方案是基于for-循环的,公认的丑陋和冗长:

for shop in df1.Shop.unique().tolist():
    df_target = df1[df1.Shop == shop]
    ...

必须有一个更有效的方法(即一个班轮)。你知道吗

如何将groupby().transform()转换为特定的行值,而不是像min()这样的函数结果?


编辑:请注意,并非所有Shop项目都提供VISA付款


Tags: forvisatransformcardminshopitemprice
1条回答
网友
1楼 · 发布于 2024-04-29 14:21:36

我认为需要^{}通过过滤DataFrame-仅VISA行:

df1['Price'] = df1['Shop'].map(df1.loc[df1['Card'] == 'VISA'].set_index('Shop')['Price'])

print (df1)
                Shop Item  Card  Price
0            Butcher    A  AMEX    0.9
1            Butcher    A  VISA    0.9
2              Baker    B  AMEX    3.5
3              Baker    B  VISA    3.5
4  Candlestick maker    C  AMEX    1.5
5  Candlestick maker    C  VISA    1.5

细节:

print (df1.loc[df1['Card'] == 'VISA'].set_index('Shop')['Price'])
Shop
Butcher              0.9
Baker                3.5
Candlestick maker    1.5
Name: Price, dtype: float64

如果得到:

InvalidIndexError: Reindexing only valid with uniquely valued Index objects

这意味着每个组有更多的VISA行。你知道吗

解决方案是聚合min

print (df1)
                Shop Item  Card  Price
0            Butcher    A  AMEX    1.5
1            Butcher    A  VISA    0.9 <-duplicated row
2            Butcher    A  VISA    1.9 <-duplicated row
3              Baker    B  AMEX    2.5
4              Baker    B  VISA    3.5
5  Candlestick maker    C  AMEX    1.5
6  Candlestick maker    C  VISA    1.5

df1['Price'] = df1['Shop'].map(df1.loc[df1['Card'] == 'VISA'].groupby('Shop')['Price'].min())
print (df1)
                Shop Item  Card  Price
0            Butcher    A  AMEX    0.9
1            Butcher    A  VISA    0.9
2            Butcher    A  VISA    0.9
3              Baker    B  AMEX    3.5
4              Baker    B  VISA    3.5
5  Candlestick maker    C  AMEX    1.5
6  Candlestick maker    C  VISA    1.5

相关问题 更多 >