So ändern Sie die Werte bestimmter Zeilen in einer Spalte eines MultiIndex-Datenrahmens in Pandas
Ich habe einen Datenrahmen (df) mit den folgenden Spalten:
print(df.columns)
['A','B','C','D','E']
Und nehmen wir an, alle Spalten enthalten Zahlen als Daten.
Dann wähle ich einige der Spalten aus, um Indizes zu werden
Index = ['A','B','C']
df.set_index(Index).sort_index()
und ich verwende es auf diese Weise für einige Analysen. Irgendwann muss ich die Zeilen der Spalte 'E' ändern, wenn der Index 'C' bestimmte Werte hat, zum Beispiel so etwas wie:
df.loc[df[(slice(None,None),slice(None,None),slice(5,10))], 'E' ] = 6
Was offensichtlich nicht funktioniert. Ich habe eine Reihe verschiedener Ansätze ausprobiert: Verwenden von Tupeln und Slices für den Index, wie in meiner obigen Zeile gezeigt, Neuanordnen der Indizes, sodass ich ein einzelnes Slice verwenden kann (Verschieben von 'C' auf die erste Ebene), versucht mit .xs (Querschnitt) usw. und ich kann es nicht. (Ich habe in der Dokumentation von .loc, .xs usw. nachgesehen) Ich finde kein Beispiel, das genau dies tut, noch finde ich eine schlüssige Antwort, dass dies nicht möglich ist. Im Moment konnte ich folgendes tun:
df.reset_index(inplace=True) # returning it back into a normal DataFrame
df.loc[(DataFrame['C'] >= 5) & (df['C'] <= 10),'E'] = 6 # Modifying normally based on column data
df.set_index(Index).sort_index() # bring it back to a multiindex
Aber das scheint nicht richtig zu sein. Es scheint mir, dass Indizes irgendwie in Scheiben geschnitten werden können, ich kann nur nicht finden, wie. Vielleicht suche ich bei Google nicht nach den richtigen Begriffen. wenn mir jemand helfen könnte oder mich in die richtige richtung weisen könnte, wäre ich sehr dankbar.
Sie können df.index.get_level_values('C')
--was ein Index-Array der Werte zurückgibt--wie unten verwenden.
import pandas as pd
df = pd.DataFrame(np.random.randint(0,10,size=(100, 5)), columns=list('ABCDE'))
df = df.set_index(['A','B','C']).sort_index()
df.loc[(df.index.get_level_values('C') <= 10) & (df.index.get_level_values('C') >= 5), 'E'] = 6
print(df)
Ergebnisse:
D E
A B C
0 0 6 3 6
2 0 6 1
7 2 6
3 6 5 6
9 1 6
... .. ..
9 3 3 5 0
6 6 6
4 3 5 7
7 6 6
6 8 6 6
Hinweis: Die Klammern um beide .get_level_values()
s sind erforderlich, da sonst die Antwort mehrdeutig ist und einen Fehler auslöst.