Zmień nazwę indeksu Pandas DataFrame

142

Mam plik csv bez nagłówka z indeksem DateTime. Chcę zmienić nazwę indeksu i kolumny, ale za pomocą df.rename () zmienia się tylko nazwa kolumny. Pluskwa? Jestem na wersji 0.12.0

In [2]: df = pd.read_csv(r'D:\Data\DataTimeSeries_csv//seriesSM.csv', header=None, parse_dates=[[0]], index_col=[0] )

In [3]: df.head()
Out[3]: 
                   1
0                   
2002-06-18  0.112000
2002-06-22  0.190333
2002-06-26  0.134000
2002-06-30  0.093000
2002-07-04  0.098667

In [4]: df.rename(index={0:'Date'}, columns={1:'SM'}, inplace=True)

In [5]: df.head()
Out[5]: 
                  SM
0                   
2002-06-18  0.112000
2002-06-22  0.190333
2002-06-26  0.134000
2002-06-30  0.093000
2002-07-04  0.098667
Mattijn
źródło
5
Osoby, które przyjdą na to pytanie w 2017 roku, sprawdź tę odpowiedź poniżej, aby zobaczyć bardzo szczegółowe wyjaśnienie rename_axismetody.
Ted Petrou
3
A dla tych, którym nie przeszkadza przeczytanie całej dobrej odpowiedzi poniżej, szybkie rozwiązanie jest df.rename_axis("Date", axis='index', inplace=True)zgodne z dokumentacją pandas.pydata.org/pandas-docs/stable/generated/… lubdf.index.names = ['Date']
tommy.carstensen

Odpowiedzi:

237

renameMetoda bierze słownika dla indeksu, która ma zastosowanie do indeksu wartości .
Chcesz zmienić nazwę na nazwę poziomu indeksu:

df.index.names = ['Date']

Dobrym sposobem na zastanowienie się nad tym jest to, że kolumny i indeks są tego samego typu obiektów ( Indexlub MultiIndex) i można je zamienić za pomocą transpozycji.

Jest to trochę mylące, ponieważ nazwy indeksów mają podobne znaczenie do kolumn, więc oto więcej przykładów:

In [1]: df = pd.DataFrame([[1, 2, 3], [4, 5 ,6]], columns=list('ABC'))

In [2]: df
Out[2]: 
   A  B  C
0  1  2  3
1  4  5  6

In [3]: df1 = df.set_index('A')

In [4]: df1
Out[4]: 
   B  C
A      
1  2  3
4  5  6

Możesz zobaczyć zmianę nazwy w indeksie, która może zmienić wartość 1:

In [5]: df1.rename(index={1: 'a'})
Out[5]: 
   B  C
A      
a  2  3
4  5  6

In [6]: df1.rename(columns={'B': 'BB'})
Out[6]: 
   BB  C
A       
1   2  3
4   5  6

Podczas zmiany nazw poziomów:

In [7]: df1.index.names = ['index']
        df1.columns.names = ['column']

Uwaga: ten atrybut jest tylko listą i możesz zmienić nazwę jako listę / mapę.

In [8]: df1
Out[8]: 
column  B  C
index       
1       2  3
4       5  6
Andy Hayden
źródło
2
Świetna odpowiedź. Wystarczy delikatnie przypomnieć, że bez "inplace =True", df1.renamenie byłoby naprawdę coś zmienić.
Sarah,
63

Aktualnie wybrana odpowiedź nie wspomina o rename_axismetodzie, za pomocą której można zmienić nazwę poziomu indeksu i kolumn.


Pandy mają pewne dziwactwa, jeśli chodzi o zmianę nazwy poziomów indeksu. Dostępna jest również nowa metoda DataFrame rename_axisdo zmiany nazw poziomów indeksu.

Przyjrzyjmy się ramce DataFrame

df = pd.DataFrame({'age':[30, 2, 12],
                       'color':['blue', 'green', 'red'],
                       'food':['Steak', 'Lamb', 'Mango'],
                       'height':[165, 70, 120],
                       'score':[4.6, 8.3, 9.0],
                       'state':['NY', 'TX', 'FL']},
                       index = ['Jane', 'Nick', 'Aaron'])

wprowadź opis obrazu tutaj

Ta ramka DataFrame ma jeden poziom dla każdego z indeksów wierszy i kolumn. Indeks wiersza i kolumny nie ma nazwy. Zmieńmy nazwę poziomu indeksu wiersza na „nazwy”.

df.rename_axis('names')

wprowadź opis obrazu tutaj

rename_axisMetoda ma również możliwość zmiany nazwy poziom kolumna zmieniając axisparametr:

df.rename_axis('names').rename_axis('attributes', axis='columns')

wprowadź opis obrazu tutaj

Jeśli ustawisz indeks z niektórymi kolumnami, nazwa kolumny stanie się nową nazwą poziomu indeksu. Dodajmy do poziomów indeksowania naszej oryginalnej ramki DataFrame:

df1 = df.set_index(['state', 'color'], append=True)
df1

wprowadź opis obrazu tutaj

Zwróć uwagę, że oryginalny indeks nie ma nazwy. Nadal możemy użyć, rename_axisale musimy przekazać jej listę o takiej samej długości, jak liczba poziomów indeksu.

df1.rename_axis(['names', None, 'Colors'])

wprowadź opis obrazu tutaj

Możesz użyć, Noneaby skutecznie usunąć nazwy poziomów indeksu.


Serie działają podobnie, ale z pewnymi różnicami

Utwórzmy serię z trzema poziomami indeksu

s = df.set_index(['state', 'color'], append=True)['food']
s

       state  color
Jane   NY     blue     Steak
Nick   TX     green     Lamb
Aaron  FL     red      Mango
Name: food, dtype: object

Możemy użyć rename_axispodobnie, jak zrobiliśmy z DataFrames

s.rename_axis(['Names','States','Colors'])

Names  States  Colors
Jane   NY      blue      Steak
Nick   TX      green      Lamb
Aaron  FL      red       Mango
Name: food, dtype: object

Zwróć uwagę, że pod nazwą Series znajduje się dodatkowy fragment metadanych Name. Podczas tworzenia serii z DataFrame ten atrybut jest ustawiany na nazwę kolumny.

Możemy przekazać renamemetodzie nazwę ciągu , aby ją zmienić

s.rename('FOOOOOD')

       state  color
Jane   NY     blue     Steak
Nick   TX     green     Lamb
Aaron  FL     red      Mango
Name: FOOOOOD, dtype: object

Ramki DataFrames nie mają tego atrybutu i infact zgłosi wyjątek, jeśli zostanie użyty w ten sposób

df.rename('my dataframe')
TypeError: 'str' object is not callable

Przed wersją pandas 0.21 mogłeś rename_axiszmienić nazwy wartości w indeksie i kolumnach. Został wycofany, więc nie rób tego

Ted Petrou
źródło
1
Czy powinieneś zamienić się df1 = df.set_index(['state', 'color'], append=True)z df1.rename_axis(['names', None, 'Colors'])?
salhin
A jeśli chcę zmienić nazwę „Nick” na „Nicolas”? Właśnie tego szukałem, kiedy wpisałem w Google „indeks zmiany nazwy pand” i znalazłem się tutaj. EDYCJA: Och, czekaj, zaakceptowana odpowiedź to wyjaśnia, po prostu nie było to dla mnie na początku oczywiste.
Ben Farmer,
Fajnie, to jedyna odpowiedź, której można użyć w połączonych zadaniach!
IanS,
19

Dla nowszych pandaswersji

df.index = df.index.rename('new name')

lub

df.index.rename('new name', inplace=True)

Ta ostatnia jest wymagana, jeśli ramka danych powinna zachować wszystkie swoje właściwości.

Serge Stroobandt
źródło
18

W Pandas w wersji 0.13 i nowszych nazwy poziomów indeksu są niezmienne (typ FrozenList) i nie można ich już ustawiać bezpośrednio. Najpierw należy użyć, Index.rename()aby zastosować nowe nazwy poziomów indeksu do indeksu, a następnie użyć, DataFrame.reindex()aby zastosować nowy indeks do DataFrame. Przykłady:

Dla wersji Pandy <0.13

df.index.names = ['Date']

Dla wersji Pandas> = 0.13

df = df.reindex(df.index.rename(['Date']))
David Smith
źródło
9
Nie prawda! W mojej wersji Pandas (0.13.1) df.index.names = ['foo'] działa dobrze!
LondonRob
5
Dziękuję, że zauważyłeś, że @LondonRob - `df.index.names = ['foo']` działa również u mnie z Pandami 0.14. Najwyraźniej został zerwany tylko na krótko i uwzględniony podczas testowania.
David Smith
1
Ustawienie nazw dla jednego z nich indexlub columnbezpośrednio powoduje zmianę obu dla mnie (na Pandach 0.19), ale nie tą metodą.
FooBar
8

Możesz również użyć Index.set_namesw następujący sposób:

In [25]: x = pd.DataFrame({'year':[1,1,1,1,2,2,2,2],
   ....:                   'country':['A','A','B','B','A','A','B','B'],
   ....:                   'prod':[1,2,1,2,1,2,1,2],
   ....:                   'val':[10,20,15,25,20,30,25,35]})

In [26]: x = x.set_index(['year','country','prod']).squeeze()

In [27]: x
Out[27]: 
year  country  prod
1     A        1       10
               2       20
      B        1       15
               2       25
2     A        1       20
               2       30
      B        1       25
               2       35
Name: val, dtype: int64
In [28]: x.index = x.index.set_names('foo', level=1)

In [29]: x
Out[29]: 
year  foo  prod
1     A    1       10
           2       20
      B    1       15
           2       25
2     A    1       20
           2       30
      B    1       25
           2       35
Name: val, dtype: int64
LondonRob
źródło
2
Czy to może zadziałać multiIndex? MultiIndex(levels=[['A', 'B', 'C', 'D', 'E', 'F'], ['Y', 'Z']], labels=[[0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5], [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]], names=['Portfolio', None])Czy można zmienić nazwę na Noneto measures?
ctrl-alt-delete
2

Jeśli chcesz użyć tego samego mapowania do zmiany nazwy obu kolumn i indeksu, możesz zrobić:

mapping = {0:'Date', 1:'SM'}
df.index.names = list(map(lambda name: mapping.get(name, name), df.index.names))
df.rename(columns=mapping, inplace=True)
danio
źródło
0
df.index.rename('new name', inplace=True)

Jest jedynym, który wykonuje pracę za mnie (pandy 0,22,0).
Bez inplace = True nazwa indeksu nie jest ustawiona w moim przypadku.

Jan H.
źródło
0

możesz użyć indexi columnsatrybuty pandas.DataFrame. UWAGA: liczba elementów listy musi odpowiadać liczbie wierszy / kolumn.

#       A   B   C
# ONE   11  12  13
# TWO   21  22  23
# THREE 31  32  33

df.index = [1, 2, 3]
df.columns = ['a', 'b', 'c']
print(df)

#     a   b   c
# 1  11  12  13
# 2  21  22  23
# 3  31  32  33
nucsit026
źródło