Zmiana nazw kolumn w pandach

1822

Mam ramkę danych przy użyciu pand i etykiet kolumn, które muszę edytować, aby zastąpić oryginalne etykiety kolumn.

Chciałbym zmienić nazwy kolumn w DataFrame, Agdzie oryginalne nazwy kolumn to:

['$a', '$b', '$c', '$d', '$e'] 

do

['a', 'b', 'c', 'd', 'e'].

Mam edytowane nazwy kolumn zapisane na liście, ale nie wiem, jak zastąpić nazwy kolumn.

użytkownik1504276
źródło
1
Możesz zajrzeć do oficjalnych dokumentów, które obejmują zmianę nazw
ccpizza

Odpowiedzi:

1826

Po prostu przypisz go do .columnsatrybutu:

>>> df = pd.DataFrame({'$a':[1,2], '$b': [10,20]})
>>> df.columns = ['a', 'b']
>>> df
   a   b
0  1  10
1  2  20
eumiro
źródło
302
Czy można zmienić nazwę nagłówka jednej kolumny?
ericmjl
112
@ericmjl: załóżmy, że chcesz zmienić nazwę pierwszej zmiennej df. Następnie możesz zrobić coś takiego:new_columns = df.columns.values; new_columns[0] = 'XX'; df.columns = new_columns
cd98
54
Wygląda na to, że mógłbyś po prostu zrobić df.columns.values ​​[0] = 'XX'
RAY
25
Żartuję, @RAY - nie rób tego. Wygląda na to, że jest to lista wygenerowana niezależnie od indeksowania przechowującego nazwę kolumny. Wykonuje niezłą robotę niszcząc nazewnictwo kolumn dla twojego df ...
Mitch Flax
433
@ericmjl yesdf.rename(columns = {'$b':'B'}, inplace = True)
nachocab
2843

ZMIEŃ NAZWY SPECJALNE KOLUMNY

Użyj df.rename()funkcji i odwołaj się do kolumn, których nazwy chcesz zmienić. Nie wszystkie kolumny muszą zostać zmienione:

df = df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'})
# Or rename the existing DataFrame (rather than creating a copy) 
df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'}, inplace=True)

Przykład minimalnego kodu

df = pd.DataFrame('x', index=range(3), columns=list('abcde'))
df

   a  b  c  d  e
0  x  x  x  x  x
1  x  x  x  x  x
2  x  x  x  x  x

Następujące metody działają i dają takie same wyniki:

df2 = df.rename({'a': 'X', 'b': 'Y'}, axis=1)  # new method
df2 = df.rename({'a': 'X', 'b': 'Y'}, axis='columns')
df2 = df.rename(columns={'a': 'X', 'b': 'Y'})  # old method  

df2

   X  Y  c  d  e
0  x  x  x  x  x
1  x  x  x  x  x
2  x  x  x  x  x

Pamiętaj, aby przypisać wynik z powrotem, ponieważ modyfikacja nie jest na miejscu. Alternatywnie podaj inplace=True:

df.rename({'a': 'X', 'b': 'Y'}, axis=1, inplace=True)
df

   X  Y  c  d  e
0  x  x  x  x  x
1  x  x  x  x  x
2  x  x  x  x  x

Od wersji 0.25 można również określić errors='raise'zgłaszanie błędów, jeśli podano niepoprawną nazwę kolumny do zmiany. Zobacz dokumenty v0.25rename() .


PONOWNE PRZYPISANIE NAGŁÓWEK KOLUMNY

Użyj za df.set_axis()pomocą axis=1i inplace=False(aby zwrócić kopię).

df2 = df.set_axis(['V', 'W', 'X', 'Y', 'Z'], axis=1, inplace=False)
df2

   V  W  X  Y  Z
0  x  x  x  x  x
1  x  x  x  x  x
2  x  x  x  x  x

Zwraca to kopię, ale możesz zmodyfikować DataFrame w miejscu, ustawiając inplace=True(jest to domyślne zachowanie dla wersji <= 0,24, ale prawdopodobnie zmieni się w przyszłości).

Możesz także przypisać nagłówki bezpośrednio:

df.columns = ['V', 'W', 'X', 'Y', 'Z']
df

   V  W  X  Y  Z
0  x  x  x  x  x
1  x  x  x  x  x
2  x  x  x  x  x
leksykalny
źródło
2
kiedy robię to z 6-kolumnową ramką danych (ramka danych <naciśnij Enter>), skrócona reprezentacja: code<klasa 'pandas.core.frame.DataFrame'> Int64Index: 1000 wpisów, 0 do 999 Kolumny danych: BodyMarkdown 1000 codedziała bez wartości null , ale kiedy robię dataframe.head (), ponownie pojawiają się stare nazwy kolumn.
darKoram
12
Boję się, SettingWithCopyWarning:gdy użyję drugiego fragmentu kodu w tej odpowiedzi.
Monica Heddneck,
czy istnieje wersja tego z zamiennikiem wyrażenia regularnego?
denfromufa
@lexual Co zrobić, jeśli dwie istniejące kolumny mają tę samą nazwę? Jak odwołać się do starej nazwy kolumny?
włóczęga,
14
Pierwsze rozwiązanie: df = df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'})zmienia wyświetlaną nazwę, ale nie elementy w podstawowej strukturze danych. Więc jeśli spróbujesz df['newName1'], pojawi się błąd. Jest inplace=Trueto konieczne, aby uniknąć tej gotchya.
irritable_phd_syndrom
402

renameSposób może zająć funkcji , na przykład:

In [11]: df.columns
Out[11]: Index([u'$a', u'$b', u'$c', u'$d', u'$e'], dtype=object)

In [12]: df.rename(columns=lambda x: x[1:], inplace=True)

In [13]: df.columns
Out[13]: Index([u'a', u'b', u'c', u'd', u'e'], dtype=object)
Andy Hayden
źródło
56
Miły. Ten uratował mi dzień:df.rename(columns=lambda x: x.lstrip(), inplace=True)
root-11
2
Podobnie jak @ root-11 - w moim przypadku pojawił się znak punktora, który nie został wydrukowany w wynikach konsoli IPython, więc musiałem usunąć więcej niż tylko białe znaki (pasek), więc:t.columns = t.columns.str.replace(r'[^\x00-\x7F]+','')
The Red Pea
9
df.rename(columns=lambda x: x.replace(' ', '_'), inplace=True)jest klejnotem, dzięki czemu możemy pisać df.Column_1_Namezamiast pisać df.loc[:, 'Column 1 Name'].
Małe tabele Bobby'ego,
179

Zgodnie z dokumentacją w pracy z danymi tekstowymi :

df.columns = df.columns.str.replace('$','')
Kadee
źródło
163

Pandy 0,21+ Odpowiedź

W wersji 0.21 wprowadzono kilka istotnych zmian w zmianie nazwy kolumny.

  • renameSposób dodał axisparametr, który może być ustawiony columnsalbo 1. Ta aktualizacja sprawia, że ​​ta metoda jest zgodna z resztą interfejsu API pand. Nadal ma parametry indexi columns, ale nie musisz już ich używać.
  • set_axisMetoda z inplacezestawem do Falsepozwala zmienić nazwy wszystkich etykiet indeksów lub kolumn z listy.

Przykłady dla pand 0.21+

Skonstruuj przykładową ramkę danych:

df = pd.DataFrame({'$a':[1,2], '$b': [3,4], 
                   '$c':[5,6], '$d':[7,8], 
                   '$e':[9,10]})

   $a  $b  $c  $d  $e
0   1   3   5   7   9
1   2   4   6   8  10

Używanie renamez axis='columns'lubaxis=1

df.rename({'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'}, axis='columns')

lub

df.rename({'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'}, axis=1)

Oba skutkują następującymi:

   a  b  c  d   e
0  1  3  5  7   9
1  2  4  6  8  10

Nadal możliwe jest użycie starej sygnatury metody:

df.rename(columns={'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'})

renameFunkcja przyjmuje również funkcje, które będą stosowane nazwy każdej kolumny.

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

lub

df.rename(lambda x: x[1:], axis=1)

Używanie set_axisz listą iinplace=False

Do set_axismetody można podać listę o długości równej liczbie kolumn (lub indeksów). Obecnie jest inplacedomyślnie ustawiony na True, ale inplacezostanie przywrócony Falsew przyszłych wydaniach.

df.set_axis(['a', 'b', 'c', 'd', 'e'], axis='columns', inplace=False)

lub

df.set_axis(['a', 'b', 'c', 'd', 'e'], axis=1, inplace=False)

Dlaczego nie użyć df.columns = ['a', 'b', 'c', 'd', 'e']?

Nie ma nic złego w przypisywaniu kolumn bezpośrednio w ten sposób. To idealnie dobre rozwiązanie.

Zaletą użycia set_axisjest to, że może być używany jako część łańcucha metod i zwraca nową kopię DataFrame. Bez tego musielibyśmy zapisać swoje pośrednie kroki łańcucha do innej zmiennej przed ponownym przypisaniem kolumn.

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

# old way
df1 = df.some_method1()
        .some_method2()
df1.columns = columns
df1.some_method3()
Ted Petrou
źródło
1
Dziękuję za Pandas 0.21+ answer- jakoś tęskniłem za częścią w części „Co nowego” ...
MaxU
1
Wydaje się, że rozwiązanie nie działa w przypadku Pandas 3.6: df.rename ({'$ a': 'a', '$ b': 'b', '$ c': 'c', '$ d': 'd ”,„ $ e ”:„ e ”}, oś =„ kolumny ”). Pobiera nieoczekiwany argument słowa kluczowego „oś”
Arthur D. Howland,
3
df.columns = ['a', 'b', 'c', 'd', 'e'] wydaje się już nie działać, pracując z wersją 0.22 Mam ostrzeżenie, że Panda nie pozwala na tworzenie kolumn za pośrednictwem nowa nazwa atrybutu . jak zmienić nazwę, jeśli wszystkie moje kolumny są takie same: /
Nabla,
Czy istnieje sposób na zmianę nazwy jednej, wielu lub wszystkich kolumn, jeśli nie znasz wcześniej nazwy kolumn, ale tylko ich indeks? Dzięki!
tommy.carstensen
to był bardzo pomocny komentarz. na przykład funkcja lambda odpowiedziała na moje pytanie, w jaki sposób wykonać następujące czynności:(df .groupby(['page',pd.Grouper(key='date',freq='MS')])['clicks'].sum() .unstack(1) .rename(lambda x: x.strftime("%Y-%m"), axis='columns') )
zmierzyć wszystkie
131

Ponieważ chcesz tylko usunąć znak $ we wszystkich nazwach kolumn, możesz po prostu zrobić:

df = df.rename(columns=lambda x: x.replace('$', ''))

LUB

df.rename(columns=lambda x: x.replace('$', ''), inplace=True)
paulo.filip3
źródło
1
Ten pomaga nie tylko w przypadku PO, ale także w ogólnych wymaganiach. Np .: aby podzielić nazwę kolumny za pomocą separatora i użyć jednej jej części.
Deepak,
77
df.columns = ['a', 'b', 'c', 'd', 'e']

Zastąpi istniejące nazwy podanymi przez Ciebie nazwami, w podanej przez Ciebie kolejności.

M PAUL
źródło
5
Nie modyfikuj df.columns.values, to źle. stackoverflow.com/questions/43291781/…
llllllllll
61
old_names = ['$a', '$b', '$c', '$d', '$e'] 
new_names = ['a', 'b', 'c', 'd', 'e']
df.rename(columns=dict(zip(old_names, new_names)), inplace=True)

W ten sposób możesz ręcznie edytować, new_namesjak chcesz. Działa świetnie, gdy trzeba zmienić nazwę tylko kilku kolumn, aby poprawić błędy ortograficzne, akcenty, usunąć znaki specjalne itp.

migloo
źródło
1
Lubię to podejście, ale myślę, że df.columns = ['a', 'b', 'c', 'd', 'e']jest prostsze.
Christopher Pearson
1
Podoba mi się ta metoda kompresji starych i nowych nazwisk. Możemy użyć, df.columns.valuesaby uzyskać stare nazwiska.
bkowshik
1
Wyświetlam widok tabelaryczny i kopiuję kolumny do old_names. Kopiuję tablicę wymagań do nowych nazw. Następnie użyj dict (zip (old_names, new_names)) Bardzo eleganckie rozwiązanie.
mythicalcoder,
Często używam podzbiorów list z czegoś takiego jak: myList = list(df) myList[10:20]itp. - więc jest to idealne rozwiązanie.
Tim Gottgetreu,
Najlepiej jest wziąć stare nazwy zgodnie z sugestią @bkowshik, a następnie edytować je i wstawić ponownie, tzn. namez = df.columns.valuesNastępnie wprowadzić pewne zmiany df.columns = namez.
pauljohn32
34

Rozwiązania z jedną linią lub rurociągiem

Skupię się na dwóch rzeczach:

  1. OP jasno stwierdza

    Mam edytowane nazwy kolumn zapisane na liście, ale nie wiem, jak zastąpić nazwy kolumn.

    Nie chcę rozwiązać problemu zastąpienia '$'lub usunięcia pierwszego znaku z nagłówka każdej kolumny. OP już zrobił ten krok. Zamiast tego chcę skupić się na zamianie istniejącego columnsobiektu na nowy, biorąc pod uwagę listę nazw kolumn zastępczych.

  2. df.columns = newgdzie newlista nazw nowych kolumn jest tak prosta, jak to tylko możliwe. Wadą tego podejścia jest to, że wymaga edycji columnsatrybutu istniejącej ramki danych i nie jest wykonywany bezpośrednio. Pokażę kilka sposobów wykonania tego za pomocą potokowania bez edytowania istniejącej ramki danych.


Konfiguracja 1
Aby skupić się na potrzebie zmiany nazwy zamiany nazw kolumn na wcześniej istniejącą listę, utworzę nową przykładową ramkę danych dfz początkowymi nazwami kolumn i niepowiązanymi nowymi nazwami kolumn.

df = pd.DataFrame({'Jack': [1, 2], 'Mahesh': [3, 4], 'Xin': [5, 6]})
new = ['x098', 'y765', 'z432']

df

   Jack  Mahesh  Xin
0     1       3    5
1     2       4    6

Rozwiązanie 1
pd.DataFrame.rename

Mówiono już, że jeśli masz słownik odwzorowujący stare nazwy kolumn na nowe nazwy kolumn, możesz użyć pd.DataFrame.rename.

d = {'Jack': 'x098', 'Mahesh': 'y765', 'Xin': 'z432'}
df.rename(columns=d)

   x098  y765  z432
0     1     3     5
1     2     4     6

Możesz jednak łatwo utworzyć ten słownik i dołączyć go do wywołania rename. Poniższe wykorzystuje fakt, że podczas iteracji dfiterujemy nazwę każdej kolumny.

# given just a list of new column names
df.rename(columns=dict(zip(df, new)))

   x098  y765  z432
0     1     3     5
1     2     4     6

Działa to świetnie, jeśli oryginalne nazwy kolumn są unikalne. Ale jeśli nie są, to się psuje.


Skonfiguruj 2
nieunikalne kolumny

df = pd.DataFrame(
    [[1, 3, 5], [2, 4, 6]],
    columns=['Mahesh', 'Mahesh', 'Xin']
)
new = ['x098', 'y765', 'z432']

df

   Mahesh  Mahesh  Xin
0       1       3    5
1       2       4    6

Rozwiązanie 2
pd.concat za pomocą keysargumentu

Najpierw zauważ, co się dzieje, gdy próbujemy użyć rozwiązania 1:

df.rename(columns=dict(zip(df, new)))

   y765  y765  z432
0     1     3     5
1     2     4     6

Nie odwzorowaliśmy newlisty jako nazw kolumn. Skończyło się to na powtarzaniu y765. Zamiast tego możemy użyć keysargumentu pd.concatfunkcji podczas iteracji po kolumnach df.

pd.concat([c for _, c in df.items()], axis=1, keys=new) 

   x098  y765  z432
0     1     3     5
1     2     4     6

Rozwiązanie 3
Zrekonstruuj. Tego należy użyć tylko, jeśli masz jeden dtypedla wszystkich kolumn. W przeciwnym razie skończysz dtype objectna wszystkich kolumnach, a ich konwersja z powrotem wymaga większej pracy słownika.

Pojedynczy dtype

pd.DataFrame(df.values, df.index, new)

   x098  y765  z432
0     1     3     5
1     2     4     6

Mieszany dtype

pd.DataFrame(df.values, df.index, new).astype(dict(zip(new, df.dtypes)))

   x098  y765  z432
0     1     3     5
1     2     4     6

Rozwiązanie 4
To sztuczka z transposei set_index. pd.DataFrame.set_indexpozwala nam ustawić wbudowany indeks, ale nie ma odpowiadającego set_columns. Możemy więc przetransponować set_indexi przetransponować z powrotem. Jednak tutaj obowiązuje ten sam zastrzeżenie pojedynczego dtypekontra mieszanego dtypez rozwiązania 3.

Pojedynczy dtype

df.T.set_index(np.asarray(new)).T

   x098  y765  z432
0     1     3     5
1     2     4     6

Mieszany dtype

df.T.set_index(np.asarray(new)).T.astype(dict(zip(new, df.dtypes)))

   x098  y765  z432
0     1     3     5
1     2     4     6

Roztwór 5
Przy użyciu lambdaw pd.DataFrame.renametym, że przełącza się pomiędzy każdym elementem new
W tym rozwiązaniu, przechodzimy lambda, które ma xale ignorowany. To także zajmuje, yale się tego nie spodziewa. Zamiast tego iterator jest podawany jako wartość domyślna, a następnie mogę go używać do przełączania pojedynczo, bez względu na wartość x.

df.rename(columns=lambda x, y=iter(new): next(y))

   x098  y765  z432
0     1     3     5
1     2     4     6

I jak wskazali mi ludzie na czacie sopython , jeśli dodam *między nimi xi y, mogę chronić moją yzmienną. Chociaż w tym kontekście nie uważam, że wymaga ochrony. Nadal warto o tym wspomnieć.

df.rename(columns=lambda x, *, y=iter(new): next(y))

   x098  y765  z432
0     1     3     5
1     2     4     6
piRSquared
źródło
Może możemy dodaćdf.rename(lambda x : x.lstrip('$'),axis=1)
YOBEN_S,
Cześć @piRSquared, czy mógłby Pan wyjaśnić, w jaki sposób pandy korzystają z funkcji lambda w Rozdziale 5? Nie do końca rozumiem, co masz na myśli, kiedy mówisz, że xjest ignorowany?
Josmoor98
33

Nazwy kolumn a nazwy serii

Chciałbym trochę wyjaśnić, co dzieje się za kulisami.

Ramki danych to zestaw Serii.

Serie z kolei są rozszerzeniem numpy.array

numpy.arraymają własność .name

To jest nazwa serii. Rzadko zdarza się, aby pandy szanowały ten atrybut, ale utrzymuje się w różnych miejscach i można go wykorzystać do zhakowania niektórych zachowań pand.

Nazywanie listy kolumn

Wiele odpowiedzi tutaj mówi o tym, df.columnsże atrybut jest, listgdy w rzeczywistości jest to Series. Oznacza to, że ma .nameatrybut.

Oto, co się stanie, jeśli zdecydujesz się wpisać nazwy kolumn Series:

df.columns = ['column_one', 'column_two']
df.columns.names = ['name of the list of columns']
df.index.names = ['name of the index']

name of the list of columns     column_one  column_two
name of the index       
0                                    4           1
1                                    5           2
2                                    6           3

Pamiętaj, że nazwa indeksu zawsze znajduje się o jedną kolumnę niżej.

Artefakty, które pozostają

.nameAtrybut pokutuje czasem. Jeśli ustawisz, df.columns = ['one', 'two']to df.one.namebędzie 'one'.

Jeśli ustawisz df.one.name = 'three'następnie df.columnsbędzie nadal daje ['one', 'two'], i df.one.namedaje'three'

ALE

pd.DataFrame(df.one) wróci

    three
0       1
1       2
2       3

Ponieważ pandy ponownie wykorzystują .namejuż zdefiniowane Series.

Nazwy kolumn wielopoziomowych

Pandy mają sposoby na tworzenie wielowarstwowych nazw kolumn. Nie ma w tym tyle magii, ale chciałem to również ująć w mojej odpowiedzi, ponieważ nie widzę tutaj nikogo, kto by to zauważył.

    |one            |
    |one      |two  |
0   |  4      |  1  |
1   |  5      |  2  |
2   |  6      |  3  |

Można to łatwo osiągnąć, ustawiając kolumny na listy, takie jak to:

df.columns = [['one', 'one'], ['one', 'two']]
firelynx
źródło
18

Jeśli masz ramkę danych, df.columns zrzuca wszystko do listy, którą możesz manipulować, a następnie ponownie przypisujesz ją do ramki danych jako nazwy kolumn ...

columns = df.columns
columns = [row.replace("$","") for row in columns]
df.rename(columns=dict(zip(columns, things)), inplace=True)
df.head() #to validate the output

Najlepszym sposobem? NIE WIEM. Sposób - tak.

Lepszy sposób oceny wszystkich głównych technik przedstawionych w odpowiedziach na pytanie znajduje się poniżej przy użyciu cProfile do pomiaru pamięci i czasu wykonania. @kadee, @kaitlyn i @eumiro miały funkcje o najszybszym czasie wykonania - chociaż te funkcje są tak szybkie, że porównujemy zaokrąglenie 0,000 i 0,001 sekundy dla wszystkich odpowiedzi. Morał: moja powyższa odpowiedź prawdopodobnie nie jest „najlepsza”.

import pandas as pd
import cProfile, pstats, re

old_names = ['$a', '$b', '$c', '$d', '$e']
new_names = ['a', 'b', 'c', 'd', 'e']
col_dict = {'$a': 'a', '$b': 'b','$c':'c','$d':'d','$e':'e'}

df = pd.DataFrame({'$a':[1,2], '$b': [10,20],'$c':['bleep','blorp'],'$d':[1,2],'$e':['texa$','']})

df.head()

def eumiro(df,nn):
    df.columns = nn
    #This direct renaming approach is duplicated in methodology in several other answers: 
    return df

def lexual1(df):
    return df.rename(columns=col_dict)

def lexual2(df,col_dict):
    return df.rename(columns=col_dict, inplace=True)

def Panda_Master_Hayden(df):
    return df.rename(columns=lambda x: x[1:], inplace=True)

def paulo1(df):
    return df.rename(columns=lambda x: x.replace('$', ''))

def paulo2(df):
    return df.rename(columns=lambda x: x.replace('$', ''), inplace=True)

def migloo(df,on,nn):
    return df.rename(columns=dict(zip(on, nn)), inplace=True)

def kadee(df):
    return df.columns.str.replace('$','')

def awo(df):
    columns = df.columns
    columns = [row.replace("$","") for row in columns]
    return df.rename(columns=dict(zip(columns, '')), inplace=True)

def kaitlyn(df):
    df.columns = [col.strip('$') for col in df.columns]
    return df

print 'eumiro'
cProfile.run('eumiro(df,new_names)')
print 'lexual1'
cProfile.run('lexual1(df)')
print 'lexual2'
cProfile.run('lexual2(df,col_dict)')
print 'andy hayden'
cProfile.run('Panda_Master_Hayden(df)')
print 'paulo1'
cProfile.run('paulo1(df)')
print 'paulo2'
cProfile.run('paulo2(df)')
print 'migloo'
cProfile.run('migloo(df,old_names,new_names)')
print 'kadee'
cProfile.run('kadee(df)')
print 'awo'
cProfile.run('awo(df)')
print 'kaitlyn'
cProfile.run('kaitlyn(df)')
andrewwowens
źródło
Dlaczego potrzebujesz metody zmiany nazwy? Coś takiego działało dla mnie # df.columns = [row.replace ('$', '') dla wiersza w df.columns]
shantanuo
Nie rozumiem części „rzeczy”. Co muszę zastąpić? Stare kolumny?
Andrea Ianni
18

Powiedzmy, że to twoja ramka danych.

wprowadź opis zdjęcia tutaj

Możesz zmienić nazwę kolumn za pomocą dwóch metod.

  1. Za pomocą dataframe.columns=[#list]

    df.columns=['a','b','c','d','e']

    wprowadź opis zdjęcia tutaj

    Ograniczeniem tej metody jest to, że jeśli trzeba zmienić jedną kolumnę, należy przekazać pełną listę kolumn. Ponadto ta metoda nie ma zastosowania do etykiet indeksu. Na przykład, jeśli zdałeś:

    df.columns = ['a','b','c','d']

    Spowoduje to błąd. Niedopasowanie długości: oczekiwana oś ma 5 elementów, nowe wartości mają 4 elementy.

  2. Inną metodą jest metoda Pandy rename(), która służy do zmiany nazwy dowolnego indeksu, kolumny lub wiersza

    df = df.rename(columns={'$a':'a'})

    wprowadź opis zdjęcia tutaj

Podobnie możesz zmienić dowolne wiersze lub kolumny.

vibhu_singh
źródło
17
df = pd.DataFrame({'$a': [1], '$b': [1], '$c': [1], '$d': [1], '$e': [1]})

Jeśli nowa lista kolumn jest w tej samej kolejności co istniejące kolumny, przypisanie jest proste:

new_cols = ['a', 'b', 'c', 'd', 'e']
df.columns = new_cols
>>> df
   a  b  c  d  e
0  1  1  1  1  1

Jeśli masz słownik ze starymi nazwami kolumn na nowe nazwy kolumn, możesz wykonać następujące czynności:

d = {'$a': 'a', '$b': 'b', '$c': 'c', '$d': 'd', '$e': 'e'}
df.columns = df.columns.map(lambda col: d[col])  # Or `.map(d.get)` as pointed out by @PiRSquared.
>>> df
   a  b  c  d  e
0  1  1  1  1  1

Jeśli nie masz odwzorowania listy lub słownika, możesz usunąć wiodący $symbol poprzez zrozumienie listy:

df.columns = [col[1:] if col[0] == '$' else col for col in df]
Alexander
źródło
2
Zamiast lambda col: d[col]ciebie mógłbyś zdać d.get... tak by to wyglądałodf.columns.map(d.get)
piRSquared
15

Zobaczmy, jak zmienić nazwę na małym przykładzie ...

1. Zmiana nazw kolumn za pomocą mapowania:

df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]}) #creating a df with column name A and B
df.rename({"A": "new_a", "B": "new_b"},axis='columns',inplace =True) #renaming column A with 'new_a' and B with 'new_b'

output:
   new_a  new_b
0  1       4
1  2       5
2  3       6

2. Indeks nazw / nazwa_wiersza za pomocą mapowania:

df.rename({0: "x", 1: "y", 2: "z"},axis='index',inplace =True) #Row name are getting replaced by 'x','y','z'.

output:
       new_a  new_b
    x  1       4
    y  2       5
    z  3       6
Amar Kumar
źródło
Najbardziej pozytywna odpowiedź ma już takie przykłady ...
Itamar Mushkin
14

Innym sposobem na zastąpienie oryginalnych etykiet kolumn jest usunięcie niechcianych znaków (tutaj „$”) z oryginalnych etykiet kolumn.

Można to zrobić, uruchamiając pętlę for nad df.columns i dołączając kolumny pozbawione do df.columns.

Zamiast tego możemy to zrobić porządnie w pojedynczym wyrażeniu, korzystając ze zrozumienia listy, takiego jak poniżej:

df.columns = [col.strip('$') for col in df.columns]

( stripmetoda w Pythonie usuwa dany znak z początku i końca łańcucha).

kait
źródło
2
Czy możesz wyjaśnić, jak / dlaczego to działa? Dzięki temu odpowiedź będzie cenniejsza dla przyszłych czytelników.
Dan Lowe,
12

Naprawdę proste po prostu użyj

df.columns = ['Name1', 'Name2', 'Name3'...]

i przypisze nazwy kolumn według kolejności, w jakiej je umieściłeś

Thodoris P.
źródło
10

Możesz użyć str.slicedo tego:

df.columns = df.columns.str.slice(1)
Anton Protopopov
źródło
1
PS: Jest to bardziej pełny odpowiednik df.columns.str[1:]... prawdopodobnie lepiej go użyć, jest krótszy i bardziej oczywisty.
cs95
9

Wiem, że to pytanie i odpowiedź została przeżuta na śmierć. Ale odniosłem się do niego w poszukiwaniu inspiracji do jednego z problemów, które miałem. Byłem w stanie go rozwiązać za pomocą fragmentów z różnych odpowiedzi, a zatem zapewniłem moją odpowiedź na wypadek, gdyby ktoś jej potrzebował.

Moja metoda jest ogólna, w której można dodawać dodatkowe ograniczniki, oddzielając przecinek delimiters=zmienną i zabezpieczając ją na przyszłość.

Kod roboczy:

import pandas as pd
import re


df = pd.DataFrame({'$a':[1,2], '$b': [3,4],'$c':[5,6], '$d': [7,8], '$e': [9,10]})

delimiters = '$'
matchPattern = '|'.join(map(re.escape, delimiters))
df.columns = [re.split(matchPattern, i)[1] for i in df.columns ]

Wynik:

>>> df
   $a  $b  $c  $d  $e
0   1   3   5   7   9
1   2   4   6   8  10

>>> df
   a  b  c  d   e
0  1  3  5  7   9
1  2  4  6  8  10
Anil_M
źródło
8

Należy pamiętać, że takie podejście nie działa w przypadku MultiIndex. W przypadku MultiIndex musisz zrobić coś takiego:

>>> df = pd.DataFrame({('$a','$x'):[1,2], ('$b','$y'): [3,4], ('e','f'):[5,6]})
>>> df
   $a $b  e
   $x $y  f
0  1  3  5
1  2  4  6
>>> rename = {('$a','$x'):('a','x'), ('$b','$y'):('b','y')}
>>> df.columns = pandas.MultiIndex.from_tuples([
        rename.get(item, item) for item in df.columns.tolist()])
>>> df
   a  b  e
   x  y  f
0  1  3  5
1  2  4  6
oxer
źródło
8

Inną opcją jest zmiana nazwy za pomocą wyrażenia regularnego:

import pandas as pd
import re

df = pd.DataFrame({'$a':[1,2], '$b':[3,4], '$c':[5,6]})

df = df.rename(columns=lambda x: re.sub('\$','',x))
>>> df
   a  b  c
0  1  3  5
1  2  4  6
sbha
źródło
6

Jeśli masz do czynienia z mnóstwem kolumn nazwanych przez system dostarczający poza twoją kontrolą, zaproponowałem następujące podejście, które jest połączeniem ogólnego podejścia i konkretnych zamienników za jednym razem.

Najpierw utwórz słownik na podstawie nazw kolumn ramki danych za pomocą wyrażeń regularnych, aby wyrzucić niektóre dodatki nazw kolumn, a następnie dodaj określone zamienniki do słownika, aby nazwać kolumny podstawowe zgodnie z oczekiwaniami w późniejszej bazie danych.

Jest to następnie stosowane do ramki danych za jednym razem.

dict=dict(zip(df.columns,df.columns.str.replace('(:S$|:C1$|:L$|:D$|\.Serial:L$)','')))
dict['brand_timeseries:C1']='BTS'
dict['respid:L']='RespID'
dict['country:C1']='CountryID'
dict['pim1:D']='pim_actual'
df.rename(columns=dict, inplace=True)
Macieja
źródło
5

Oprócz rozwiązania, które już zostało dostarczone, możesz zamienić wszystkie kolumny podczas czytania pliku. Możemy to wykorzystać namesi header=0to zrobić.

Najpierw tworzymy listę nazw, które lubimy używać jako nazwy kolumn:

import pandas as pd

ufo_cols = ['city', 'color reported', 'shape reported', 'state', 'time']
ufo.columns = ufo_cols

ufo = pd.read_csv('link to the file you are using', names = ufo_cols, header = 0)

W takim przypadku wszystkie nazwy kolumn zostaną zastąpione nazwami, które masz na liście.

Stryker
źródło
4

Oto fajna mała funkcja, której lubię używać, aby ograniczyć pisanie:

def rename(data, oldnames, newname): 
    if type(oldnames) == str: #input can be a string or list of strings 
        oldnames = [oldnames] #when renaming multiple columns 
        newname = [newname] #make sure you pass the corresponding list of new names
    i = 0 
    for name in oldnames:
        oldvar = [c for c in data.columns if name in c]
        if len(oldvar) == 0: 
            raise ValueError("Sorry, couldn't find that column in the dataset")
        if len(oldvar) > 1: #doesn't have to be an exact match 
            print("Found multiple columns that matched " + str(name) + " :")
            for c in oldvar:
                print(str(oldvar.index(c)) + ": " + str(c))
            ind = input('please enter the index of the column you would like to rename: ')
            oldvar = oldvar[int(ind)]
        if len(oldvar) == 1:
            oldvar = oldvar[0]
        data = data.rename(columns = {oldvar : newname[i]})
        i += 1 
    return data   

Oto przykład tego, jak to działa:

In [2]: df = pd.DataFrame(np.random.randint(0,10,size=(10, 4)), columns=['col1','col2','omg','idk'])
#first list = existing variables
#second list = new names for those variables
In [3]: df = rename(df, ['col','omg'],['first','ohmy']) 
Found multiple columns that matched col :
0: col1
1: col2

please enter the index of the column you would like to rename: 0

In [4]: df.columns
Out[5]: Index(['first', 'col2', 'ohmy', 'idk'], dtype='object')
seeiespi
źródło
1
Przypadek użycia takiej funkcji jest niezwykle rzadki. W większości przypadków wiem, czego szukam i na co chcę zmienić nazwę, po prostu sam to przypisuję / modyfikuję.
cs95
1
@ cs95 Pracuję z dużymi ankietami krajowymi lub międzynarodowymi, w których zmienne będą miały zakodowane nazwy zmiennych, które zaczynają się od prefiksów w zależności od opcji odpowiedzi, skal Likerta i rozgałęzień (takich jak EDU_2913.443, EDU_2913.421, ...). Ta funkcja była dla mnie bardzo przydatna podczas pracy z tego rodzaju zestawami, rozumiem, jeśli jednak nie jest ona dla ciebie :)
patrz
3

Zmiana nazw kolumn w pandach jest łatwym zadaniem.

df.rename(columns = {'$a':'a','$b':'b','$c':'c','$d':'d','$e':'e'},inplace = True)
Nirali Khoda
źródło
2

Zakładając, że możesz użyć wyrażenia regularnego. To rozwiązanie eliminuje potrzebę ręcznego kodowania przy użyciu wyrażenia regularnego

import pandas as pd
import re

srch=re.compile(r"\w+")

data=pd.read_csv("CSV_FILE.csv")
cols=data.columns
new_cols=list(map(lambda v:v.group(),(list(map(srch.search,cols)))))
data.columns=new_cols
Kaustubh J
źródło
2
Dobrą praktyką dotyczącą przepełnienia stosu jest dodanie wyjaśnienia, dlaczego Twoje rozwiązanie powinno działać lub jest lepsze niż istniejące rozwiązania. Aby uzyskać więcej informacji, przeczytaj Jak odpowiedzieć .
Samuel Liew
Zauważ, że najlepiej oceniana odpowiedź wymaga pewnego rodzaju twardego kodowania, a najgorsza odpowiedź wymaga jedynie podejścia opisowego i proceduralnego?
Kaustubh J
Istnieją lepsze (bardziej czytelne) rozwiązania, które również wykorzystują wyrażenie regularne. Robi to znacznie więcej niż powinno w przypadku prostej operacji zmiany nazwy. Istnieje również niebezpieczeństwo, że wzorzec nie będzie pasował do niczego, w którym to przypadku nie zrobiłeś nic, aby obsłużyć błędy.
cs95,