2017-02-02 2 views
2

Ich habe Datenrahmen wie untenWie mit Binning mit kompliziertem Zustand in Pandas schwenken

age type days 
1 a 1 
2 b 3 
2 b 4 
3 a 5 
4 b 2 
6 c 1 
7 f 0 
7 d 4 
10 e 2 
14 a 1 

zuerst würde ich mit dem Alter Binning wie

Alter

[0~4]

age type days 
1 a 1 
2 b 3 
2 b 4 
3 a 5 
4 b 2 

Dann summiere und zähle die Tage durch Gruppieren mit type

Dann möchte ich diese Methode auf eine andere Binns anwenden.

[5 ~ 9] [11 ~ 14]

Mein gewünschtes Ergebnis ist unter

[0~4]   [5~9]  [10~14] 
    sum count sum count sum count 
a 6 2  0 0  1 1 
b 9 3  0 0  0 0 
c 0 0  1 1  0 0 
d 0 0  4 1  0 0 
e 0 0  0 0  2 1 
f 0 0  0 1  0 0 

Wie dies geschehen kann? Es ist sehr kompliziert für mich ..

Antwort

1

Betrachten wir ein pivot_table mit pd.cut, wenn Sie die Reihenfolge der Spalten als Zählung und Summe nicht zusammen unter dem bin gepaart nicht zu viel kümmern. Mit Manipulation können Sie diese Reihenfolge ändern.

df['bin'] = pd.cut(df.age, [0,4,9,14]) 

pvtdf = df.pivot_table(index='type', columns=['bin'], values='days', 
         aggfunc=('count', 'sum')).fillna(0) 

#  count     sum    
# bin (0, 4] (4, 9] (9, 14] (0, 4] (4, 9] (9, 14] 
# type            
# a  2.0 0.0  1.0 6.0 0.0  1.0 
# b  3.0 0.0  0.0 9.0 0.0  0.0 
# c  0.0 1.0  0.0 0.0 1.0  0.0 
# d  0.0 1.0  0.0 0.0 4.0  0.0 
# e  0.0 0.0  1.0 0.0 0.0  2.0 
# f  0.0 1.0  0.0 0.0 0.0  0.0 
2

Wir verwenden einige Stapel-und Groupby-Operationen, um uns zu der gewünschten Ausgabe.

string_ = io.StringIO('''age type days 
         1 a 1 
         2 b 3 
         2 b 4 
         3 a 5 
         4 b 2 
         6 c 1 
         7 f 0 
         7 d 4 
         10 e 2 
         14 a 1''') 
df = pd.read_csv(string_, sep='\s+') 

df['age_bins'] = pd.cut(df['age'], [0,4,9,14]) 

df_stacked = df.groupby(['age_bins', 'type']).agg({'days': np.sum, 
         'type': 'count'}).transpose().stack().fillna(0) 
df_stacked.rename(index={'days': 'sum', 'type': 'count'}, inplace=True) 

>>> df_stacked 
age_bins (0, 4] (4, 9] (9, 14] 
     type       
sum a  6.0  0.0  1.0 
     b  9.0  0.0  0.0 
     c  0.0  1.0  0.0 
     d  0.0  4.0  0.0 
     e  0.0  0.0  2.0 
     f  0.0  0.0  0.0 
count a  2.0  0.0  1.0 
     b  3.0  0.0  0.0 
     c  0.0  1.0  0.0 
     d  0.0  1.0  0.0 
     e  0.0  0.0  1.0 
     f  0.0  1.0  0.0 

produziert Dies schließt nicht die genaue Ausgabe, die Sie aufgelistet, aber es ist ähnlich, und ich denke, es ist einfacher zu indizieren sein wird und Daten aus abgerufen werden. Alternativ könnten Sie Folgendes verwenden, um etwas wie die gewünschte Ausgabe zu erhalten.

>>> df_stacked.unstack(level=0) 
age_bins (0, 4]  (4, 9]  (9, 14]  
      count sum count sum count sum 
type           
a   2.0 6.0 0.0 0.0  1.0 1.0 
b   3.0 9.0 0.0 0.0  0.0 0.0 
c   0.0 0.0 1.0 1.0  0.0 0.0 
d   0.0 0.0 1.0 4.0  0.0 0.0 
e   0.0 0.0 0.0 0.0  1.0 2.0 
f   0.0 0.0 1.0 0.0  0.0 0.0