【问题标题】:Converting long table to wide and creating columns according to the rows将长表转换为宽表并根据行创建列
【发布时间】:2018-03-29 00:42:01
【问题描述】:

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

Customer_ID     Category   Products 
  1               Veg         A
  2               Veg         B
  3              Fruit        A   
  3              Fruit        B
  3               Veg         B 
  1              Fruit        A
  3               Veg         C 
  1              Fruit        C

我想找出每个类别的每个客户 ID 购买了哪些产品,并相应地为每个产品创建一个列。输出如下所示:

Customer_ID     Category    Pro_1    Pro_2     Pro_3
  1               Veg        A        NA         NA
  1              Fruit       A        NA         C
  2               Veg        NA       B          NA
  3               Veg        NA       B          C
  3              Fruit       A        B          NA

【问题讨论】:

    标签: python python-2.7 pandas pivot-table


    【解决方案1】:

    groupbyunstack 一起使用,但如果重复的行数据连接在一起:

    df = df.groupby(['Customer_ID','Category','Products'])['Products'].sum().unstack()
    df.columns = ['Pro_{}'.format(x) for x in range(1, len(df.columns)+1)]
    df = df.reset_index()
    print (df)
       Customer_ID Category Pro_1 Pro_2 Pro_3
    0            1    Fruit     A  None     C
    1            1      Veg     A  None  None
    2            2      Veg  None     B  None
    3            3    Fruit     A     B  None
    4            3      Veg  None     B     C
    

    另一个带有辅助列的解决方案,三元组必须是唯一的:

    #if not unique triples remove duplicates
    df = df.drop_duplicates(['Customer_ID','Category','Products'])
    
    df['a'] = df['Products']
    df = df.set_index(['Customer_ID','Category','Products'])['a'].unstack()
    df.columns = ['Pro_{}'.format(x) for x in range(1, len(df.columns)+1)]
    df = df.reset_index()
    print (df)
       Customer_ID Category Pro_1 Pro_2 Pro_3
    0            1    Fruit     A  None     C
    1            1      Veg     A  None  None
    2            2      Veg  None     B  None
    3            3    Fruit     A     B  None
    4            3      Veg  None     B     C
    

    【讨论】:

    • 这里的问题是,当我们取消堆叠时,我们最终会得到与产品唯一值的数量一样多的产品。这会导致新列与客户 ID 和类别不紧密。我正在尝试根据组级别的产品创建列
    • 可以通过它改变输入数据吗?
    • 更改输入数据是什么意思?
    【解决方案2】:

    使用crosstab 的另一个选项:

    pd.crosstab([df['Customer_ID'],df['Category']], df['Products'])
    

    输出:

    Products              A  B  C
    Customer_ID Category         
    1           Fruit     1  0  1
                Veg       1  0  0
    2           Veg       0  1  0
    3           Fruit     1  1  0
                Veg       0  1  1
    

    之后,您可以重置索引以获得与您想要的类似的解决方案。

    df = df.reset_index()
    Products  Customer_ID Category  A  B  C
    0                   1    Fruit  1  0  1
    1                   1      Veg  1  0  0
    2                   2      Veg  0  1  0
    3                   3    Fruit  1  1  0
    4                   3      Veg  0  1  1
    

    【讨论】:

    • 交叉制表发生在所有产品上,我们如何才能只针对客户 ID 和类别级别的产品?
    【解决方案3】:

    试试这个:(不要介意 IO 的东西,它只是用于简单的复制/粘贴)

    import pandas as pd
    from io import StringIO
    df = pd.read_csv(StringIO("""
    Customer_ID     Category   Products 
      1               Veg         A
      2               Veg         B
      3              Fruit        A   
      3              Fruit        B
      3               Veg         B 
      1              Fruit        A
      3               Veg         C 
      1              Fruit        C"""), sep='\s+')
    df = df.join(pd.get_dummies(df['Products']))
    g = df.groupby(['Customer_ID', 'Category']).sum()
    print(g)
    

    输出:

                          A  B  C
    Customer_ID Category         
    1           Fruit     1  0  1
                Veg       1  0  0
    2           Veg       0  1  0
    3           Fruit     1  1  0
                Veg       0  1  1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-01
      • 2018-03-01
      • 2021-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-21
      • 2020-02-13
      相关资源
      最近更新 更多