2017-10-17 5 views
2

j'ai une trame de données qui ressemblent à ceci:Conversion longue table à colonnes et de la création selon les lignes

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 

Je veux trouver le pour chaque numéro de client pour chaque catégorie produits qui ont été achetés, et créez une colonne pour chaque produit en conséquence. La sortie se présente comme suit:

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 

Répondre

1

Utilisez groupby avec unstack, mais si les doublons lignes données sont concanecate ensemble:

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 

Une autre solution avec colonne d'aide, triplets doit être unique:

#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 
+0

Le problème ici est que lorsque nous dépilons nous nous retrouvons avec autant de produits que le nombre de valeurs uniques des produits. Cela se traduit par de nouvelles colonnes qui ne correspondent pas à l'ID client et à la catégorie. J'essaie de créer des colonnes basées sur les produits au niveau du groupe – owise

+0

Est-il possible de modifier les données d'entrée par lui? – jezrael

+0

que voulez-vous dire en changeant les données d'entrée? – owise

0

Essayez ceci: (ne me dérange pas la chose IO, il est juste pour simple copier/coller)

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) 

sortie:

     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 
1

Une autre option utilisant crosstab:

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

sortie:

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 

Ensuite, vous pouvez réinitialiser l'index pour une solution similaire à ce que vous vouliez.

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 
+0

Le crosstabing se produit sur tous les produits, comment pouvons-nous simplement cibler les produits sur le niveau d'identification client et de catégorie? – owise