Zmień nazwę określonej kolumny (kolumn) w pandach

182

Mam ramkę danych o nazwie data. Jak zmienić nazwę jedynego nagłówka kolumny? Na przykład, gdpaby log(gdp)?

data =
    y  gdp  cap
0   1    2    5
1   2    3    9
2   8    7    2
3   3    4    7
4   6    7    7
5   4    8    3
6   8    2    8
7   9    9   10
8   6    6    4
9  10   10    7
natsuki_2002
źródło
7
Zdecydowanie się pokrywają, ale nie było dla mnie od razu jasne na podstawie „Zmiana nazwy kolumn w pandach”, że można wyodrębnić pojedynczy element kolumny do zmiany nazwy. Oczywiście z perspektywy czasu jest to oczywiste i gdybym kopał głębiej, prawdopodobnie bym się tego domyślił, ale myślę, że to pytanie / odpowiedź lepiej na to wskazuje.
jeremiahbuddha

Odpowiedzi:

360
data.rename(columns={'gdp':'log(gdp)'}, inplace=True)

Program rename, w którym akceptuje dyktando jako parametr, columnswięc wystarczy przekazać dyktando jednym wpisem.

Zobacz także powiązane

EdChum
źródło
3
Zajmuje to bardzo dużo czasu w przypadku dużej ramki danych, więc uważam, że powoduje to skopiowanie całej ramki danych w pamięci?
elgehelge
1
@elgehelge nie powinno to robić, większość operacji na pandach zwróci kopię, a niektóre zaakceptują inplaceparametr, jeśli ignoruje ten parametr, to jest to błąd, czy możesz robić czasy z parametrem i bez niego, spróbuj także czegoś takiego new_df = df.rename(columns={'new_name':'old_name'})i zobacz, czy to jest szybszy czy nie
EdChum
1
@ EdChum Thanks. Usunięcie inplaceparametru prawie podwoiło czas z 14 do 26 sekund. Ale 14 sekund to jeszcze sporo czasu na zmianę nagłówka…
elgehelge
2
tylko jedna uwaga, uwaga! jeśli kolumna docelowa nie istnieje (błędna pisownia nazwy lub coś podobnego), nie da to nic bez błędu lub ostrzeżenia.
Amir
1
@Quastiat To trochę przygnębiające, dlaczego niektóre z tych prostych operacji są po prostu szybsze, wykonując zrozumienie listy. Zasadniczo jednak, jeśli nie masz bardzo dużego df, to nie powinno to mieć znaczenia, chyba że zmieniasz nazwę wielu kolumn na duży df
EdChum
27

Znacznie szybszą implementacją byłoby użycie, list-comprehensionjeśli chcesz zmienić nazwę pojedynczej kolumny.

df.columns = ['log(gdp)' if x=='gdp' else x for x in df.columns]

Jeśli zajdzie potrzeba zmiany nazwy wielu kolumn, użyj wyrażeń warunkowych, takich jak:

df.columns = ['log(gdp)' if x=='gdp' else 'cap_mod' if x=='cap' else x for x in df.columns]

Lub skonstruować za pomocą mapowania dictionaryi wykonać list-comprehensionz jego getpracy przez ustawienie wartości domyślnej, jak stare nazwy:

col_dict = {'gdp': 'log(gdp)', 'cap': 'cap_mod'}   ## key→old name, value→new name

df.columns = [col_dict.get(x, x) for x in df.columns]

Czasy:

%%timeit
df.rename(columns={'gdp':'log(gdp)'}, inplace=True)
10000 loops, best of 3: 168 µs per loop

%%timeit
df.columns = ['log(gdp)' if x=='gdp' else x for x in df.columns]
10000 loops, best of 3: 58.5 µs per loop
Nickil Maveli
źródło
Chciałbym użyć tej metody, ale niestety nie działa, pd.merge_asof()ponieważ jest to wyrażenie :(.
thdoan
14

Jak zmienić nazwę określonej kolumny w pandach?

Od wersji 0.24 +, aby zmienić nazwę jednej (lub więcej) kolumn naraz,

Jeśli chcesz zmienić nazwę WSZYSTKICH kolumn naraz,

  • DataFrame.set_axis()metoda z axis=1. Przekaż sekwencję podobną do listy. Dostępne są również opcje modyfikacji w miejscu.

rename z axis=1

df = pd.DataFrame('x', columns=['y', 'gdp', 'cap'], index=range(5))
df

   y gdp cap
0  x   x   x
1  x   x   x
2  x   x   x
3  x   x   x
4  x   x   x

W wersji 0.21+ możesz teraz określić axisparametr za pomocą rename:

df.rename({'gdp':'log(gdp)'}, axis=1)
# df.rename({'gdp':'log(gdp)'}, axis='columns')
    
   y log(gdp) cap
0  x        x   x
1  x        x   x
2  x        x   x
3  x        x   x
4  x        x   x

(Zauważ, że renamedomyślnie nie jest to miejsce na miejscu, więc będziesz musiał przypisać wynik z powrotem ).

Ten dodatek został wprowadzony w celu poprawy spójności z resztą interfejsu API. Nowy axisargument jest analogiczny do columnsparametru - robią to samo.

df.rename(columns={'gdp': 'log(gdp)'})

   y log(gdp) cap
0  x        x   x
1  x        x   x
2  x        x   x
3  x        x   x
4  x        x   x

rename akceptuje również wywołanie zwrotne, które jest wywoływane raz dla każdej kolumny.

df.rename(lambda x: x[0], axis=1)
# df.rename(lambda x: x[0], axis='columns')

   y  g  c
0  x  x  x
1  x  x  x
2  x  x  x
3  x  x  x
4  x  x  x

W tym konkretnym scenariuszu chciałbyś użyć

df.rename(lambda x: 'log(gdp)' if x == 'gdp' else x, axis=1)

Index.str.replace

Podobnie jak w przypadku replacemetody łańcuchów znaków w Pythonie, indeks i serie pand (tylko typ obiektu) definiują (zwektoryzowaną) str.replacemetodę zastępowania ciągów i wyrażeń regularnych.

df.columns = df.columns.str.replace('gdp', 'log(gdp)')
df
 
   y log(gdp) cap
0  x        x   x
1  x        x   x
2  x        x   x
3  x        x   x
4  x        x   x

Zaletą tego w porównaniu z innymi metodami jest str.replaceobsługa wyrażeń regularnych (domyślnie włączona). Więcej informacji można znaleźć w dokumentacji.


Przekazywanie listy do set_axiszaxis=1

Zadzwoń set_axisz listą nagłówków. Lista musi mieć taką samą długość jak kolumny / rozmiar indeksu. set_axismutuje oryginalną ramkę DataFrame domyślnie, ale można określić, inplace=Falseaby zwrócić zmodyfikowaną kopię.

df.set_axis(['cap', 'log(gdp)', 'y'], axis=1, inplace=False)
# df.set_axis(['cap', 'log(gdp)', 'y'], axis='columns', inplace=False)

  cap log(gdp)  y
0   x        x  x
1   x        x  x
2   x        x  x
3   x        x  x
4   x        x  x

Uwaga: w przyszłych wersjach inplacebędzie domyślnie True.

Tworzenie łańcuchów metod Po co
wybierać, set_axisskoro już mamy skuteczny sposób przypisywania kolumn df.columns = ...? Jak pokazuje Ted Petrou w [ta odpowiedź], ( https://stackoverflow.com/a/46912050/4909087 )set_axis jest przydatne podczas próby łączenia metod w łańcuch.

Porównać

# new for pandas 0.21+
df.some_method1()
  .some_method2()
  .set_axis()
  .some_method3()

Przeciw

# old way
df1 = df.some_method1()
        .some_method2()
df1.columns = columns
df1.some_method3()

Pierwsza jest bardziej naturalną i swobodną składnią.

cs95
źródło
3

Istnieje co najmniej pięć różnych sposobów zmiany nazw określonych kolumn w pandach. Wymieniłem je poniżej wraz z linkami do oryginalnych odpowiedzi. Zmierzyłem również czas tych metod i stwierdziłem, że działają mniej więcej tak samo (chociaż YMMV w zależności od zestawu danych i scenariusza). Poniższy przypadek testowy polega na zmianie nazw kolumn A M N Zna A2 M2 N2 Z2w ramce danych z kolumnami Ana Zmiliony wierszy.

# Import required modules
import numpy as np
import pandas as pd
import timeit

# Create sample data
df = pd.DataFrame(np.random.randint(0,9999,size=(1000000, 26)), columns=list('ABCDEFGHIJKLMNOPQRSTUVWXYZ'))

# Standard way - https://stackoverflow.com/a/19758398/452587
def method_1():
    df_renamed = df.rename(columns={'A': 'A2', 'M': 'M2', 'N': 'N2', 'Z': 'Z2'})

# Lambda function - https://stackoverflow.com/a/16770353/452587
def method_2():
    df_renamed = df.rename(columns=lambda x: x + '2' if x in ['A', 'M', 'N', 'Z'] else x)

# Mapping function - https://stackoverflow.com/a/19758398/452587
def rename_some(x):
    if x=='A' or x=='M' or x=='N' or x=='Z':
        return x + '2'
    return x
def method_3():
    df_renamed = df.rename(columns=rename_some)

# Dictionary comprehension - https://stackoverflow.com/a/58143182/452587
def method_4():
    df_renamed = df.rename(columns={col: col + '2' for col in df.columns[
        np.asarray([i for i, col in enumerate(df.columns) if 'A' in col or 'M' in col or 'N' in col or 'Z' in col])
    ]})

# Dictionary comprehension - https://stackoverflow.com/a/38101084/452587
def method_5():
    df_renamed = df.rename(columns=dict(zip(df[['A', 'M', 'N', 'Z']], ['A2', 'M2', 'N2', 'Z2'])))

print('Method 1:', timeit.timeit(method_1, number=10))
print('Method 2:', timeit.timeit(method_2, number=10))
print('Method 3:', timeit.timeit(method_3, number=10))
print('Method 4:', timeit.timeit(method_4, number=10))
print('Method 5:', timeit.timeit(method_5, number=10))

Wynik:

Method 1: 3.650640267
Method 2: 3.163998427
Method 3: 2.998530871
Method 4: 2.9918436889999995
Method 5: 3.2436501520000007

Skorzystaj z metody, która jest dla Ciebie najbardziej intuicyjna i najłatwiejsza do wdrożenia w Twojej aplikacji.

thdoan
źródło