Переименование столбцов в панд

У меня есть фрейм данных с использованием панд и меток столбцов, которые мне нужно отредактировать, чтобы заменить исходные метки столбцов.

Я хотел бы изменить имена столбцов в фрейме данных A где исходные имена столбцов:

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

to

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

у меня есть отредактированные имена столбцов хранятся в списке, но я не знаю как заменить имена столбцов.

28 ответов


просто назначить :

>>> df = pd.DataFrame({'$a':[1,2], '$b': [10,20]})
>>> df.columns = ['a', 'b']
>>> df
   a   b
0  1  10
1  2  20

использовать df.rename() function и обратитесь к столбцам, которые будут переименованы. Не все столбцы должны быть переименованы:

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)

на rename метод может принимать функция, например:

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)

как задокументировано в http://pandas.pydata.org/pandas-docs/stable/text.html:

df.columns = df.columns.str.replace('$','')

поскольку вы хотите удалить только $ sign во всех именах столбцов, вы можете просто сделать:

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

или

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

Панды 0.21+ Ответ

там были некоторые значительные обновления для переименования столбцов в версии 0.21.

  • на rename метод добавил axis параметр, который может быть установлен в columns или 1. Это обновление делает этот метод соответствует остальной части API pandas. У него все еще есть index и columns параметры, но вы больше не вынуждены использовать их.
  • на set_axis метод С inplace значение False позволяет переименовать все метки индекса или столбца со списком.

примеры для панд 0.21+

построить образец фрейма данных:

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

используя rename С axis='columns' или axis=1

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

или

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

как следствие:

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

по-прежнему можно использовать подпись старого метода:

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

на


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

Он заменит существующие имена именами, которые вы предоставляете, в порядке, который вы предоставляете.


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)

таким образом, вы можете вручную изменить new_names Как вы хотите. Отлично работает, когда вам нужно переименовать только несколько столбцов, чтобы исправить ошибки, акценты, удалить специальные символы и т. д.


Я думаю, что этот метод полезен:

df.rename(columns={"old_column_name1":"new_column_name1", "old_column_name2":"new_column_name2"})

этот метод позволяет изменять имена столбцов по отдельности.


имена столбцов против имен серий

я хотел бы немного объяснить, что происходит за кулисами.

таблицы данных представляют собой набор серий.

являясь list когда на самом деле это Series. Это означает, что у него есть .

это произойдет, если вы решите заполнить имя колонки 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

обратите внимание, что имя индекса всегда идет на один столбец ниже.

артефакты, которые задерживаются

на .name атрибут иногда задерживается. Если вы установите df.columns = ['one', 'two'] тогда df.one.name будет 'one'.

если вы устанавливаете df.one.name = 'three' затем df.columns по-прежнему ['one', 'two'] и df.one.name даст вам 'three'

но

pd.DataFrame(df.one) вернутся

    three
0       1
1       2
2       3

потому что панды использует .name уже определен Series.

многоуровневые имена столбцов

панды имеет способы делать многоуровневые имена столбцов. Существует не так много магии, но я хотел, чтобы покрыть это в моем ответе тоже, так как я не вижу, чтобы кто-то подхватил это здесь.

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

это легко достижимо, установив столбцы в списки, например:

df.columns = [['one', 'one'], ['one', 'two']]

одна линия или трубопровод решений

я сосредоточусь на двух вещах:

  1. OP четко заявляет

    у меня есть отредактированные имена столбцов хранятся в списке, но я не знаю как заменить имена столбцов.

    я не хочу решать проблему того, как заменить '$' или снимите первый символ с каждого заголовка столбца. ОП уже сделал этот шаг. Вместо этого я хочу сосредоточиться на замене существующее columns объект с новым заданным списком имен столбцов замены.

  2. df.columns = new здесь new список новых имен столбцов так же прост, как он получает. Недостатком этого подхода является то, что он требует редактирования существующего фрейма данных columns атрибут, и это не делается inline. Я покажу несколько способов выполнить это с помощью конвейерной передачи без редактирования существующего фрейма данных.


настройка 1
Чтобы сосредоточиться на необходимости переименования имен столбцов replace с уже существующим списком, я создам новый образец dataframe df с начальными именами столбцов и несвязанными новыми именами столбцов.

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

Решение 1
pd.DataFrame.rename

уже было сказано, что если у вас был словарь, сопоставляющий старые имена столбцов с новыми именами столбцов, вы можете использовать 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

однако вы можете легко создать этот словарь и включить его в вызов rename. Следующее использует тот факт, что при итерации по df, мы повторяем имя каждого столбца.

# 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

это отлично работает, если ваши оригинальные имена столбцов являются уникальными. Но если это не так, тогда все рушится.


настройка 2
неуникальные столбцы

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

решение 2
pd.concat с помощью keys аргумент

во-первых, обратите внимание, что происходит, когда мы пытаемся использовать раствор 1:

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

   y765  y765  z432
0     1     3     5
1     2     4     6

мы не карта new список имен столбцов. Мы закончили тем, что повторили y765. Вместо этого мы можем использовать на pd.concat функция при итерации по столбцам df.

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

   x098  y765  z432
0     1     3     5
1     2     4     6

решение 3
Реконструировать. Это следует использовать, только если у вас есть один dtype для всех столбцов. В противном случае вы получите dtype object для всех столбцов и их преобразования обратно требуется больше словарной работы.

один dtype

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

   x098  y765  z432
0     1     3     5
1     2     4     6

смешанные 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

решение 4
Это трюк с transpose и set_index. pd.DataFrame.set_index позволяет нам установить индекс inline, но нет соответствующего set_columns. Так что мы можем транспонировать, тогда set_index, и транспонировать. Однако тот же сингл dtype против смешанных dtype оговорка из решения 3 применяется здесь.

один dtype

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

   x098  y765  z432
0     1     3     5
1     2     4     6

смешанные 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

решение 5
Используйте lambda на pd.DataFrame.rename это циклы через каждый элемент new
В этом решении мы передаем лямбда, которая принимает x но игнорирует его. Это также занимает y но не ожидает этого. Вместо этого итератор задается как значение по умолчанию, и я могу использовать его для цикла по одному за раз, независимо от того, какое значение x есть.

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

   x098  y765  z432
0     1     3     5
1     2     4     6

и, как указал мне на людей в sopython чат, если я добавить * между x и y, я могу защитить мой y переменной. Хотя в этом контексте я не считаю, что он нуждается в защите. Это все еще стоит упомянуть.

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

   x098  y765  z432
0     1     3     5
1     2     4     6

DataFrame -- df.переименовать() будет работать.

df.rename(columns = {'Old Name':'New Name'})

df-это фрейм данных, который у вас есть, и Старое Название - имя столбца хотите изменить, тогда Новое Имя это новое имя, которое вы меняете. Этот встроенный метод DataFrame упрощает работу.


df = pd.DataFrame({'$a': [1], '$b': [1], '$c': [1], '$d': [1], '$e': [1]})

если ваш новый список столбцов находится в том же порядке, что и существующие столбцы, назначение простое:

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

если бы у вас был словарь, набранный на старых именах столбцов для новых имен столбцов, вы могли бы сделать следующее:

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

если у вас нет списка или сопоставления словаря, вы можете удалить ведущий $ символ через понимание списка:

df.columns = [col[1:] if col[0] == '$' else col for col in df]

Если у вас есть фрейм данных, df.столбцы сбрасывают все в список, которым можно управлять, а затем переназначают в фрейм данных имена столбцов...

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

лучший способ? IDK. Способ - да.

лучший способ оценки всех основных методов, предложенных в ответах на вопрос, ниже, используя cProfile для измерения памяти и времени выполнения. @kadee, @kaitlyn, & @eumiro имели функции с самым быстрым временем выполнения - хотя эти функции таковы быстро мы сравниваем округление .000 и .001 секунда на все ответы. Мораль: мой ответ выше, вероятно, не является "лучшим" способом.

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)')

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

является функциональным способом решения этого


другой способ заменить исходные метки столбцов-это удалить ненужные символы (здесь '$') из исходных меток столбцов.

Это можно было сделать, выполнив цикл for над df.столбцы и добавление разделенных столбцов в df.столбцы.

вместо этого мы можем сделать это аккуратно в одном заявлении, используя понимание списка, как показано ниже:

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

(strip метод в Python удаляет данный символ из начала и конца строка.)


Я знаю, что этот вопрос и ответ уже разжевано до смерти. Но я сослался на него для вдохновения для одной из проблем, которые у меня были . Я смог решить его, используя фрагменты из разных ответов, поэтому предоставил свой ответ на случай, если он кому-то понадобится.

мой метод является общим, в котором вы можете добавить дополнительные разделители запятымиdelimiters= переменной и будущих.

рабочая Код:

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 ]

выход:

>>> 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

Real simple просто используйте

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

и он назначит имена столбцов по порядку, в котором вы их поместите


можно использовать str.slice для этого:

df.columns = df.columns.str.slice(1)


обратите внимание, что этот подход не работает для Мультииндекса. Для Мультииндекса вам нужно сделать что-то вроде следующего:

>>> 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

переименовать столбцы фрейма данных и заменить формат

import pandas as pd

data = {'year':[2015,2011,2007,2003,1999,1996,1992,1987,1983,1979,1975],
        'team':['Australia','India','Australia','Australia','Australia','Sri Lanka','Pakistan','Australia','India','West Indies','West Indies'],
        }
df = pd.DataFrame(data)

#Rename Columns
df.rename(columns={'year':'Years of Win','team':'Winning Team'}, inplace=True)

#Replace format
df = df.columns.str.replace(' ', '_')

Если вам приходится иметь дело с нагрузками столбцов, названных предоставляющей системой вне вашего контроля, я придумал следующий подход, который представляет собой комбинацию общего подхода и конкретных замен за один раз.

сначала я создаю словарь из имен столбцов фрейма данных, используя выражения регулярных выражений, чтобы отбросить некоторые приложения имен столбцов и затем я добавляю определенные замены в словарь, чтобы назвать основные столбцы, как ожидалось позже в получении база данных.

Это затем применяется к фрейму данных за один раз.

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)

другой вариант-переименовать с помощью регулярного выражения:

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

попробуйте это. Это работает для меня

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

в случае, если вам не нужны имена строк df.columns = ['a', 'b',index=False]


вот изящная маленькая функция, которую я люблю использовать, чтобы сократить ввод:

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   

вот пример того, как это работает:

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')

Renaming columns while reading the Dataframe: 

>>> df = pd.DataFrame({'$a': [1], '$b': [1], '$c': [1]}).rename(columns = 
         {'$a' : 'a','$b':'b','$c':'c'})

Out[1]: 
   a  b  c
0  1  1  1