2013-05-30 8 views
16

Ich möchte einige Werte aus einer Spalte in meinem DataFrame ändern. Im Moment habe ich eine Ansicht von Auswahl über die Multi-Index von meinem ursprünglichen df (und Änderung ändert sich df).Weisen Sie dem MultiIndex DataFrame neue Werte zu

Hier ist ein Beispiel:

In [1]: arrays = [np.array(['bar', 'bar', 'baz', 'qux', 'qux', 'bar']), 
        np.array(['one', 'two', 'one', 'one', 'two', 'one']), 
        np.arange(0, 6, 1)] 
In [2]: df = pd.DataFrame(randn(6, 3), index=arrays, columns=['A', 'B', 'C']) 

In [3]: df 
        A   B   C 
bar one 0 -0.088671 1.902021 -0.540959 
    two 1 0.782919 -0.733581 -0.824522 
baz one 2 -0.827128 -0.849712 0.072431 
qux one 3 -0.328493 1.456945 0.587793 
    two 4 -1.466625 0.720638 0.976438 
bar one 5 -0.456558 1.163404 0.464295 

Ich versuche, ein Stück df auf einen skalaren Wert zu ändern:

In [4]: df.ix['bar', 'two', :]['A'] 
Out[4]: 
1 0.782919 
Name: A, dtype: float64 

In [5]: df.ix['bar', 'two', :]['A'] = 9999 
# df is unchanged 

ich wirklich mehrere Werte in der Spalte ändern möchten (und seit Indizierung gibt einen Vektor zurück, keinen skalaren Wert, ich denke, das würde mehr Sinn machen):

In [6]: df.ix['bar', 'one', :]['A'] = [999, 888] 
# again df remains unchanged 

Ich benutze Pandas 0.11. Gibt es einen einfachen Weg, dies zu tun?

Die aktuelle Lösung besteht darin, df aus einem neuen zu erstellen und Werte zu ändern, die ich möchte. Aber es ist nicht elegant und kann auf komplexen Datenrahmen sehr schwer sein. Meiner Meinung nach sollte das Problem von .ix und .loc kommen, das eine Ansicht aber eine Kopie zurückgibt.

+0

warum -1 vote? Kannst du es wenigstens erklären? – HadiM

+0

+1 eine ausgezeichnete Frage, zu einem verwirrenden Problem. Ich kann nur daran denken, dass es downvoted wurde, weil der Titel nicht beschreibend ist? (aber wer weiß!) –

+1

Sorry für den Titel, aber ich bin kein englischer Muttersprachler und das Thema ist etwas komplex, so dass es schwer ist, einen guten zu finden :-) Wenn du mir einen Titel einreichen willst, kann ich den aktuellen ändern ein. – HadiM

Antwort

10

Sortieren der Rahmen, dann wählen/Satz ein Tupel für die Multi-Index

In [12]: df = pd.DataFrame(randn(6, 3), index=arrays, columns=['A', 'B', 'C']) 

In [13]: df 
Out[13]: 
        A   B   C 
bar one 0 -0.694240 0.725163 0.131891 
    two 1 -0.729186 0.244860 0.530870 
baz one 2 0.757816 1.129989 0.893080 
qux one 3 -2.275694 0.680023 -1.054816 
    two 4 0.291889 -0.409024 -0.307302 
bar one 5 1.697974 -1.828872 -1.004187 

In [14]: df = df.sortlevel(0) 

In [15]: df 
Out[15]: 
        A   B   C 
bar one 0 -0.694240 0.725163 0.131891 
     5 1.697974 -1.828872 -1.004187 
    two 1 -0.729186 0.244860 0.530870 
baz one 2 0.757816 1.129989 0.893080 
qux one 3 -2.275694 0.680023 -1.054816 
    two 4 0.291889 -0.409024 -0.307302 

In [16]: df.loc[('bar','two'),'A'] = 9999 

In [17]: df 
Out[17]: 
        A   B   C 
bar one 0 -0.694240 0.725163 0.131891 
     5  1.697974 -1.828872 -1.004187 
    two 1 9999.000000 0.244860 0.530870 
baz one 2  0.757816 1.129989 0.893080 
qux one 3 -2.275694 0.680023 -1.054816 
    two 4  0.291889 -0.409024 -0.307302 

Sie es auch das Sortieren mit heraus tun verwenden können, wenn Sie den vollständigen Index angeben, zum Beispiel

In [23]: df.loc[('bar','two',1),'A'] = 999 

In [24]: df 
Out[24]: 
        A   B   C 
bar one 0 -0.113216 0.878715 -0.183941 
    two 1 999.000000 -1.405693 0.253388 
baz one 2 0.441543 0.470768 1.155103 
qux one 3 -0.008763 0.917800 -0.699279 
    two 4 0.061586 0.537913 0.380175 
bar one 5 0.857231 1.144246 -2.369694 

die Sortiertiefe

In [27]: df.index.lexsort_depth 
Out[27]: 0 

In [28]: df.sortlevel(0).index.lexsort_depth 
Out[28]: 3 

Der letzte Teil Ihrer Frage zu prüfen, mit einer Liste zuweisen (beachten Sie, dass Sie die gleiche Anzahl von Elementen haben müssen Sie zu ersetzen versuchen), und das muss für diese Arbeit sortiert werden

In [12]: df.loc[('bar','one'),'A'] = [999,888] 

In [13]: df 
Out[13]:  
                    A         B         C 
bar one 0  999.000000 -0.645641  0.369443 
        5  888.000000 -0.990632 -0.577401 
    two 1   -1.071410  2.308711  2.018476 
baz one 2    1.211887  1.516925  0.064023 
qux one 3   -0.862670 -0.770585 -0.843773 
    two 4   -0.644855 -1.431962  0.232528 
+0

Also, es geht nur ums Sortieren ... Ok, ich werde das in Zukunft benutzen. Danke für den Trick! – HadiM

+1

Yep, lass dies dein Freund werden: http://pandas.pydata.org/pandas-docs/dev/indexing.html#the-need-for-sortnessness – Jeff

Verwandte Themen