2016-11-07 2 views
3

Ich möchte den Weg ändern Name einer bestimmten Spalte in einem mehrstufigen Datenrahmen.Pandas: Ändern Sie einen bestimmten Spaltennamen in Datenrahmen mit Multilevel-Spalten

Mit diesen Daten:

data = { 
    ('A', '1', 'I'): [1, 2, 3, 4, 5], 
    ('B', '2', 'II'): [1, 2, 3, 4, 5], 
    ('C', '3', 'I'): [1, 2, 3, 4, 5], 
    ('D', '4', 'II'): [1, 2, 3, 4, 5], 
    ('E', '5', 'III'): [1, 2, 3, 4, 5], 
} 

dataDF = pd.DataFrame(data) 

Dieser Code funktioniert nicht:

dataDF.rename(columns = {('A', '1', 'I'):('Z', '100', 'Z')}, inplace=True) 

Ergebnis:

A B C D E 
    1 2 3 4 5 
    I II I II III 
0 1 1 1 1 1 
1 2 2 2 2 2 
2 3 3 3 3 3 
3 4 4 4 4 4 
4 5 5 5 5 5 

Und auch nicht:

dataDF.columns.values[0] = ('Z', '100', 'Z') 

Ergebnis:

A B C D E 
    1 2 3 4 5 
    I II I II III 
0 1 1 1 1 1 
1 2 2 2 2 2 
2 3 3 3 3 3 
3 4 4 4 4 4 
4 5 5 5 5 5 

Aber mit Kombination von oben Codes arbeiten !!!

dataDF.columns.values[0] = ('Z', '100', 'Z') 
dataDF.rename(columns = {('A', '1', 'I'):('Z', '100', 'Z')}, inplace=True) 
dataDF 

Ergebnis:

Z B C D E 
    100 2 3 4 5 
    Z II I II III 
0 1 1 1 1 1 
1 2 2 2 2 2 
2 3 3 3 3 3 
3 4 4 4 4 4 
4 5 5 5 5 5 

Ist dieser Fehler von Pandas?

Antwort

4

Das ist meine Theorie

Pandas will nicht pd.Index s wandelbar sein. Das können wir sehen, ob wir versuchen, das erste Element des Index selbst

dataDF.columns[0] = ('Z', '100', 'Z') 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-32-2c0b76762235> in <module>() 
----> 1 dataDF.columns[0] = ('Z', '100', 'Z') 

//anaconda/envs/3.5/lib/python3.5/site-packages/pandas/indexes/base.py in __setitem__(self, key, value) 
    1372 
    1373  def __setitem__(self, key, value): 
-> 1374   raise TypeError("Index does not support mutable operations") 
    1375 
    1376  def __getitem__(self, key): 

TypeError: Index does not support mutable operations 

Aber Pandas können nicht kontrollieren, zu ändern, was Sie tun, um die values Attribut.

dataDF.columns.values[0] = ('Z', '100', 'Z') 

wir sehen, dass dataDF.columns gleich aussieht, aber dataDF.columns.values spiegelt deutlich die Veränderung. Leider ist df.columns.values nicht, was auf dem Display des Datenrahmens angezeigt wird.


Auf der anderen Seite scheint dies wirklich wie es funktionieren sollte. Die Tatsache, dass es sich für mich nicht falsch anfühlt.

dataDF.rename(columns={('A', '1', 'I'): ('Z', '100', 'Z')}, inplace=True) 

Ich glaube, der Grund, warum dies funktioniert nur, nachdem die Werte geändert hat, ist, dass rename die Rekonstruktion der Säulen zwingt, indem du den Werten suchen. Da wir die Werte ändern, funktioniert es jetzt. Dies ist außergewöhnlich kludgy und ich empfehle nicht, einen Prozess zu bauen, der darauf beruht.


meine Empfehlung

  • identifizieren Lage von Spaltennamen
  • assign Namen der Spalte mit dem Array von Werten
  • neue Spalten von Grund auf ändern wollen bauen, explicity

from_col = ('A', '1', 'I') 
to_col = ('Z', '100', 'Z') 
colloc = dataDF.columns.get_loc(from_col) 
cvals = dataDF.columns.values 
cvals[colloc] = to_col 

dataDF.columns = pd.MultiIndex.from_tuples(cvals.tolist()) 

dataDF 

[![enter code here][1]][1] 
+0

danke für deine erklärung! –

+0

Sie sind willkommen – piRSquared

0

Sie können einfach ändern wie DF.columns.levels=[[u'Z', u'B', u'C', u'D', u'E'],[u'5', u'2', u'3', u'4', u'5'],[u'IIIIII', u'II', u'III']]

+0

immer noch bin ich mir nicht sicher, ob sein Bug als dein Sprichwort. –

+0

danke für deine erklärung! –

Verwandte Themen