【问题标题】:How to convert the table in pandas?如何在熊猫中转换表格?
【发布时间】:2021-06-10 22:55:50
【问题描述】:

我有下面的数据框:

df = pd.DataFrame(
    [
        ['A11', 'One', 'Person1', 'Yes'],
        ['A11', 'One', 'Person2', 'No'], 
        ['B22', 'Two', 'Person3', 'Yes'],
        ['B22', 'Two', 'Person1', 'No'],
        ['B22', 'Two', 'Person4', 'No'],
        ['C33', 'Three', 'Person5', 'Yes']
    ],
    columns=['Code', 'Name', 'Person', 'Valid']
)
Code Name Person Valid
0 A11 One Person1 Yes
1 A11 One Person2 No
2 B22 Two Person3 Yes
3 B22 Two Person1 No
4 B22 Two Person4 No
5 C33 Three Person5 Yes

我想要实现的是:

Code Name Person A Valid A Person B Valid B Person C Valid C
0 A11 One Person1 Yes Person2 No NaN NaN
1 B22 Two Person3 Yes Person1 No Person4 Yes
2 C33 Three Person5 Yes NaN NaN NaN NaN

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    试试:

    from string import ascii_uppercase
    
    l = (
        df.groupby(["Code", "Name"])
        .agg(list)
        .apply(lambda x: list(zip(x["Person"], x["Valid"])), axis=1)
    )
    
    data = []
    for a in l:
        data.append({})
        for i, (b, c) in zip(ascii_uppercase, a):
            data[-1].update({f"Person {i}": b, f"Valid {i}": c})
    
    print(
        pd.concat([l.reset_index()[["Code", "Name"]], pd.DataFrame(data)], axis=1)
    )
    

    打印:

      Code   Name Person A Valid A Person B Valid B Person C Valid C
    0  A11    One  Person1     Yes  Person2      No      NaN     NaN
    1  B22    Two  Person3     Yes  Person1      No  Person4      No
    2  C33  Three  Person5     Yes      NaN     NaN      NaN     NaN
    

    【讨论】:

      【解决方案2】:

      我们开始吧(我相信这很丑 - 那里可能会更好),

      • 使用GroupBy + cumcount 为每一行创建唯一索引
      • 使用unstack 给出你想要的形状
      • 然后展平 MultiIndex 列
      >>> from string import ascii_uppercase
      >>> person_id = df.groupby('Code').cumcount()
      >>> person_id = person_id.map(dict(enumerate(ascii_uppercase)))
      >>> unpivoted = df.set_index(['Code', person_id]).unstack(1)
      >>> unpivoted
             Name             Person                   Valid          
                A    B    C        A        B        C     A    B    C
      Code                                                            
      A11     One  One  NaN  Person1  Person2      NaN   Yes   No  NaN
      B22     Two  Two  Two  Person3  Person1  Person4   Yes   No   No
      C33   Three  NaN  NaN  Person5      NaN      NaN   Yes  NaN  NaN
      >>> unpivoted.columns = unpivoted.columns.map(lambda tup: f'{tup[0]} {tup[1]}')
      >>> unpivoted.reset_index()
           Name A Name B Name C Person A Person B Person C Valid A Valid B Valid C
      0  A11    One    One    NaN  Person1  Person2      NaN     Yes      No     NaN
      1  B22    Two    Two    Two  Person3  Person1  Person4     Yes      No      No
      2  C33  Three    NaN    NaN  Person5      NaN      NaN     Yes     NaN     NaN
      

      如果列的顺序对您很重要,您可以通过交换级别并对列多索引进行排序(在展平列之前)对它们进行重新排序:

      >>> unpivoted = unpivoted.reorder_levels([1, 0], axis='columns').sort_index(axis='columns')
      >>> unpivoted.columns = unpivoted.columns.map(lambda tup: f'{tup[1]} {tup[0]}')
      >>> unpivoted
           Name A Person A Valid A Name B Person B Valid B Name C Person C Valid C
      Code                                                                        
      A11     One  Person1     Yes    One  Person2      No    NaN      NaN     NaN
      B22     Two  Person3     Yes    Two  Person1      No    Two  Person4      No
      C33   Three  Person5     Yes    NaN      NaN     NaN    NaN      NaN     NaN
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-26
        • 2020-04-30
        • 2023-03-07
        • 2014-01-04
        • 2019-02-25
        • 2023-03-27
        • 2021-05-27
        • 1970-01-01
        相关资源
        最近更新 更多