Pandas用条件ch从长到宽重塑多列数据帧

2024-05-15 08:24:38 发布

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

我有一个pandas数据框,如下所示:

id     group    type    action    cost
101    A        1                 10
101    A        1       repair    3
102    B        1                 5
102    B        1       repair    7
102    B        1       grease    2
102    B        1       inflate   1
103    A        2                 12
104    B        2                 9

我需要将其从长改为宽,但取决于action列的值,如下所示:

id     group    type    action_std    action_extra
101    A        1       10            3
102    B        1       5             10
103    A        2       12            0
104    B        2       9             0

换句话说,对于具有空action字段的行,cost值应放在action_std列下,而对于具有非空action字段的行,cost值应汇总在action_extra列下

我尝试了几种groupby/agg/pivot的组合,但找不到任何完全有效的解决方案


Tags: 数据idpandastypegroupactionextraagg
0条回答
网友
1楼 · 发布于 2024-05-15 08:24:38

感谢您的提示,这是我最终最喜欢的解决方案(也因为它的简单性):

df["action_std"] = df["cost"].where(df["action"] == "")
df["action_extra"] = df["cost"].where(df["action"] != "")
df = df.groupby(["id", "group", "type"])["action_std", "action_extra"].sum().reset_index()
网友
2楼 · 发布于 2024-05-15 08:24:38

我建议您简单地将cost列拆分为cost列和cost_extra列。如下所示:

import numpy as np

result = df.assign(
    cost_extra=lambda df: np.where(
        df['action'].notnull(), df['cost'], np.nan
    )
).assign(
    cost=lambda df: np.where(
        df['action'].isnull(), df['cost'], np.nan
    )
).groupby(
    ["id", "group", "type"]
)["cost", "cost_extra"].agg(
    "sum"
)

result看起来像:

                cost  cost_extra
id  group type                  
101 A     1     10.0         3.0
102 B     1      5.0        10.0
103 A     2     12.0         0.0
104 B     2      9.0         0.0
网友
3楼 · 发布于 2024-05-15 08:24:38

unstack检查groupby

df.cost.groupby([df.id,df.group,df.type,df.action.eq('')]).sum().unstack(fill_value=0)
action          False  True 
id  group type              
101 A     1         3     10
102 B     1        10      5
103 A     2         0     12
104 B     2         0      9

相关问题 更多 >