2014-06-18 15 views
9

Ich habe ein Datenrahmen, grouped, mit Multiindex Spalten wie folgt:Pandas Datenrahmen mit Multiindex Spalte - fusionieren Ebenen

import pandas as pd 
codes = ["one","two","three"]; 
colours = ["black", "white"]; 
textures = ["soft", "hard"]; 
N= 100 # length of the dataframe 
df = pd.DataFrame({ 'id' : range(1,N+1), 
        'weeks_elapsed' : [random.choice(range(1,25)) for i in range(1,N+1)], 
        'code' : [random.choice(codes) for i in range(1,N+1)], 
        'colour': [random.choice(colours) for i in range(1,N+1)], 
        'texture': [random.choice(textures) for i in range(1,N+1)], 
        'size': [random.randint(1,100) for i in range(1,N+1)], 
        'scaled_size': [random.randint(100,1000) for i in range(1,N+1)] 
        }, columns= ['id', 'weeks_elapsed', 'code','colour', 'texture', 'size', 'scaled_size']) 
grouped = df.groupby(['code', 'colour']).agg({'size': [np.sum, np.average, np.size, pd.Series.idxmax],'scaled_size': [np.sum, np.average, np.size, pd.Series.idxmax]}).reset_index() 

>> grouped 
    code colour  size       scaled_size       
        sum average size idxmax   sum average size idxmax 
0 one black 1031 60.647059 17  81  185.153944 10.891408 17  47 
1 one white  481 37.000000 13  53  204.139249 15.703019 13  53 
2 three black  822 48.352941 17  6  123.269405 7.251141 17  31 
3 three white 1614 57.642857 28  50  285.638337 10.201369 28  37 
4 two black  523 58.111111  9  85  80.908912 8.989879  9  88 
5 two white  669 41.812500 16  78  82.098870 5.131179 16  78 
[6 rows x 10 columns] 

Wie kann ich flach/die Spaltenindexstände wie fusionieren: „Ebene 1 | Level2“, z.B. size|sum, scaled_size|sum. etc? Wenn das nicht möglich ist, gibt es einen Weg zu groupby() wie ich oben ohne Erstellen von Multi-Index-Spalten?

Antwort

6

man konnte immer die Spalten ändern:

grouped.columns = ['%s%s' % (a, '|%s' % b if b else '') for a, b in grouped.columns] 
+1

wenn eine der Spalten in Ebene 1 gleich' 0' ist, dann ignoriert der obige Ausdruck sie hier: 'b if b else "". Stattdessen habe ich 'b! = ''' Verwendet, also 'grouped.columns = ['% s% s'% (a, '|% s'% b wenn b! = '' Else '') für a, b in gruppierten Spalten] '. Dies könnte nützlich sein, nachdem 'groupby' verwendet wurde, das Spalten mit Zahlen beginnend mit 0 aufzählt. –

+1

es würde ein Problem mit' None' geben, also müßten Sie 'if (b == 0 oder b)' machen , aber immer noch ein guter Ruf – acushner

+0

@acusher, Sie haben Recht, obwohl 'wenn b ist nicht keine' sollte die einfache Art und Weise es auszudrücken ... –

0

ich bin nicht sicher, ob ich verstehe, was du meinst;) aber Sie zwei Spalten mit String-Daten in Index so kombinieren könnte:

df['merged_ix'] = df.code + '|' + df.colour 
df.set_index(df.merged_ix, inplace=True) 
+0

Danke, aber es ist nicht das, was ich frage für . Ich habe die Frage bearbeitet, um sie klarer zu machen. Ich möchte die zwei Ebenen in den Spaltennamen loswerden. Wenn es zwei Ebenen gibt, ni wollen sie zu einer zusammenfassen, wie 'size | sum' – Rhubarb

9

Es gibt ein Potenzial, einen besseren Weg, mehr Pythonie Weg, um Multiindex-Spalten zu glätten.

grouped.columns = grouped.columns.map('|'.join) 

print(grouped) 

Ausgang:

code| colour| size|sum size|average size|size size|idxmax \ 
0 one black  862  53.875000   16   14 
1 one white  554  46.166667   12   18 
2 three black  842  49.529412   17   90 
3 three white  740  56.923077   13   97 
4 two black  1541  61.640000   25   50 

    scaled_size|sum scaled_size|average scaled_size|size scaled_size|idxmax 
0    6980   436.250000    16     77 
1    6101   508.416667    12     13 
2    7889   464.058824    17     64 
3    6329   486.846154    13     73 
4   12809   512.360000    25     23 

bearbeiten Hand numerische Spalten verwenden:

grouped.columns = grouped.columns.map('{0[0]}|{0[1]}'.format) 

Ausgang:

code| colour| size|sum size|average size|size size|idxmax \ 
0 one black  734  52.428571   14   30 
1 one white  1110  65.294118   17   88 
2 three black  930  51.666667   18   3 
3 three white  1140  51.818182   22   20 
4 two black  656  38.588235   17   77 
5 two white  704  58.666667   12   17 

    scaled_size|sum scaled_size|average scaled_size|size scaled_size|idxmax 
0    8229   587.785714    14     57 
1    8781   516.529412    17     73 
2   10743   596.833333    18     21 
3   10240   465.454545    22     26 
4    9982   587.176471    17     16 
5    6537   544.750000    12     49 
+0

es funktioniert nicht, wenn Sie numerische Spalten haben 'MultiIndex (levels = [ [u'col_a ', u'col_b', u'col_c '], [7950230.0, 12304568.0]], etiketten = [[0, 0, 1], [0, 1, 1]], namen = [lev , sublev ']) ' gibt zurück' TypeError: Sequenzelement 1: erwartete Zeichenfolge, float gefunden' –

+0

@PabloA grouped.columns.map ('{0 [0]} | {0 [1]}'. Format) –

+1

Große Lösung. Pythonisch und flexibel. – Kevin

Verwandte Themen