【问题标题】:Pandas DataFrame pivot (reshape?)Pandas DataFrame 枢轴(重塑?)
【发布时间】:2020-09-17 00:57:41
【问题描述】:

我似乎无法做到这一点......这就是我想要做的:

import pandas as pd

df = pd.DataFrame({
    'item_id': [1,1,3,3,3],
    'contributor_id': [1,2,1,4,5],
    'contributor_role': ['sing', 'laugh', 'laugh', 'sing', 'sing'],
    'metric_1': [80, 90, 100, 92, 50],
    'metric_2': [180, 190, 200, 192, 150]
})

--->

   item_id contributor_id contributor_role   metric_1  metric_2  
0     1          1             sing              80       180  
1     1          2             laugh             90       190  
2     3          1             laugh             100      200  
3     3          4             sing              92       192  
4     3          5             sing              50       150  

我想把它改造成:

     item_id        SING_1_contributor_id SING_1_metric_1 SING_1_metric_2  SING_2_contributor_id SING_2_metric_1 SING_2_metric_2 ... LAUGH_1_contributor_id LAUGH_1_metric_1 LAUGH_1_metric_2 ... <LAUGH_2_...>

0       1               1                 80              180                   N/A                N/A              N/A      ...          2                    90           190 ... N/A..

1       3               4                 92              192                   5                  50               150      ...          1                    100          200 ... N/A..

基本上,对于每个 item_id,我想将所有相关数据收集到一行中。每个项目可以有多种类型的贡献者,并且每种类型都有一个最大值(例如,最大 SING 贡献者 = 每个项目 A,最大 LAUGH 贡献者 = 每个项目 B)。每个贡献者都有一组指标(但对于同一个贡献者,不同项目/贡献者类型的值可能不同)。

我可能可以通过一些看似低效的方法来实现这一点(例如循环和匹配然后填充模板df),但我想知道是否有更有效的方法来实现这一点,可能通过巧妙地指定index/@ 987654324@ / columns 在枢轴操作(或任何其他方法..)中。

提前感谢您的任何建议!

编辑:

最终将 Ben 的脚本改编为以下内容:

df['role_count'] = df.groupby(['item_id', 'contributor_role']).cumcount().add(1).astype(str)
df['contributor_role'] = df.apply(lambda row: row['contributor_role'] + '_' + row['role_count'], axis=1)
df = df.set_index(['item_id','contributor_role']).unstack()
df.columns = ['_'.join(x) for x in df.columns.values]

【问题讨论】:

    标签: python pandas dataframe pivot reshape


    【解决方案1】:

    您可以使用cumcount 创建附加密钥,然后执行unstack

    df['newkey']=df.groupby('item_id').cumcount().add(1).astype(str)
    df['contributor_id']=df['contributor_id'].astype(str)
    s = df.set_index(['item_id','newkey']).unstack().sort_index(level=1,axis=1)
    s.columns=s.columns.map('_'.join)
    s
    Out[38]: 
            contributor_id_1 contributor_role_1  ...  metric_1_3  metric_2_3
    item_id                                      ...                        
    1                      1               sing  ...         NaN         NaN
    3                      1         messaround  ...        50.0       150.0
    

    【讨论】:

    • 嘿,本!这看起来很有希望!有没有办法将contributor_role 信息也移动到列名中?所以我们有像SING_1_contributor_idSING_1_metric_1...这样的列?
    • 嗯,仍然不是很准确,但它对我找出其余部分很有帮助,请参阅我的编辑以了解我最终使用的最终脚本。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2020-04-13
    • 2017-04-08
    • 2020-08-14
    • 2019-01-14
    • 2018-04-12
    • 2017-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多