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

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

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

К

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

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

2075
user1504276 5 Июл 2012 в 18:21

21 ответ

Лучший ответ

Просто назначьте его атрибуту .columns:

>>> df = pd.DataFrame({'$a':[1,2], '$b': [10,20]})
>>> df.columns = ['a', 'b']
>>> df
   a   b
0  1  10
1  2  20
1718
eumiro 5 Июл 2012 в 14:23

Другой вариант - переименовать, используя регулярное выражение:

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
8
sbha 7 Июл 2018 в 02:07

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

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
2
Kaustubh J 12 Апр 2019 в 03:34
df.rename(index=str,columns={'A':'a','B':'b'})

https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.rename.html

15
Yog 29 Авг 2018 в 13:35

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

Произошли некоторые существенные обновления переименования столбцов в версии 0.21.

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

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

Построить образец DataFrame:

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

Функция rename также принимает функции, которые будут применяться к каждому имени столбца.

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

Или

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

Использование set_axis со списком и inplace=False

Вы можете предоставить список методу set_axis, длина которого равна числу столбцов (или индекса). В настоящее время inplace по умолчанию равен True, но inplace будет по умолчанию False в будущих выпусках.

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

Или

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

Почему бы не использовать df.columns = ['a', 'b', 'c', 'd', 'e']?

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

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

# 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()
162
JohnE 17 Ноя 2017 в 19:31

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

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

Лучший способ? ИДК . Способ - да.

Ниже представлен лучший способ оценки всех основных методов, предложенных в ответах на вопрос, с использованием cProfile для измерения памяти и времени выполнения. У @kadee, @kaitlyn, & @eumiro были функции с самым быстрым временем выполнения - хотя эти функции настолько быстры, что мы сравниваем округление в 0,000 и 0,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)')
17
andrewwowens 7 Сен 2016 в 02:24
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]
17
Alexander 13 Сен 2017 в 12:24

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

Мой метод является общим, в котором вы можете добавить дополнительные разделители, разделяя запятую 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
9
Anil_M 4 Авг 2016 в 20:26

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

df.columns = df.columns.str.slice(1)
10
Anton Protopopov 28 Янв 2016 в 17:31

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)
383
smci 20 Окт 2019 в 22:06
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 по своему желанию. Прекрасно работает, когда вам нужно переименовать только несколько столбцов, чтобы исправить неправильное написание, акценты, удалить специальные символы и т. Д.

59
migloo 21 Май 2015 в 17:54

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

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

Затем это применяется к кадру данных за один раз.

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)
6
Chris A 5 Июл 2019 в 11:46

ПЕРЕИМЕНУЙТЕ СПЕЦИАЛЬНЫЕ КОЛОННЫ

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

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)

Пример минимального кода

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

Следующие методы работают и выдают одинаковый результат:

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

Не забудьте присвоить результат обратно, так как модификация не на месте. В качестве альтернативы укажите 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

Начиная с v0.25, вы также можете указать errors='raise' для выдачи ошибок, если указан неверный столбец для переименования. См. v0. 25 rename() документов.


ИЗМЕНИТЬ ЗАГОЛОВОК КОЛОННЫ

Используйте df.set_axis() с axis=1 и inplace=False (чтобы вернуть копию).

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

Это возвращает копию, но вы можете изменить DataFrame на месте, установив inplace=True (это поведение по умолчанию для версий <= 0.24, но, вероятно, изменится в будущем).

Вы также можете назначить заголовки напрямую:

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
2669
cs95 29 Май 2019 в 19:50

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

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')
4
seeiespi 18 Май 2018 в 23:36

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

>>> 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
8
oxer 29 Авг 2016 в 21:27

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

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

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

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

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

13
piet.t 5 Июл 2017 в 13:19

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

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

Датафреймы представляют собой набор Series.

Серия, в свою очередь, является продолжением numpy.array

numpy.array имеют свойство .name

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

Наименование списка столбцов

Многие ответы здесь говорят о том, что атрибут df.columns является list, хотя на самом деле это Series. Это означает, что у него есть атрибут .name.

Вот что произойдет, если вы решите заполнить имя столбца 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']]
33
firelynx 29 Сен 2016 в 12:30

Очень просто использовать

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

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

12
Thodoris P 29 Ноя 2015 в 19:22
df.columns = ['a', 'b', 'c', 'd', 'e']

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

75
Mike_K 12 Окт 2018 в 05:45

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

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

ИЛИ

df.rename(columns=lambda x: x.replace('$', ''), inplace=True)
130
paulo.filip3 26 Мар 2014 в 10:20