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

1831

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

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

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

в

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

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

user1504276
источник
1
Возможно, вы захотите проверить официальные документы, которые охватывают переименование меток столбцов: pandas.pydata.org/pandas-docs/stable/user_guide/text.html
ccpizza

Ответы:

1832

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

>>> df = pd.DataFrame({'$a':[1,2], '$b': [10,20]})
>>> df.columns = ['a', 'b']
>>> df
   a   b
0  1  10
1  2  20
eumiro
источник
303
Можно ли изменить название заголовка одного столбца?
ericmjl
112
@ericmjl: предположим, вы хотите изменить имя первой переменной df. Тогда вы можете сделать что-то вроде:new_columns = df.columns.values; new_columns[0] = 'XX'; df.columns = new_columns
CD98
54
Похоже, вы могли бы просто сделать df.columns.values ​​[0] = 'XX'
RAY
25
Шучу, @RAY - не делай этого. Похоже, это список, сгенерированный независимо от индексации, хранящей имя столбца. Хорошая работа по уничтожению имен столбцов для вашего df ...
Митч Лен
433
@ericmjl даdf.rename(columns = {'$b':'B'}, inplace = True)
начокаб
2850

ПЕРЕИМЕНОВАТЬ КОНКРЕТНЫЕ КОЛОННЫ

Используйте 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.25rename() .


ИЗМЕНИТЬ КОЛОННУ

использование 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
lexual
источник
2
когда я делаю это с 6-столбцовым фреймом данных (dataframe <press enter>), сокращенное представление: code<class 'pandas.core.frame.DataFrame'> Int64Index: 1000 записей, от 0 до 999 столбцов данных: BodyMarkdown 1000 не-null codeработает , но когда я делаю dataframe.head (), старые имена для столбцов снова появляются.
ДарКорам
12
Я ужасаюсь, SettingWithCopyWarning:когда использую второй фрагмент кода в этом ответе.
Моника Хедднек
Есть ли версия этого с заменой регулярных выражений?
Денфромуфа
@lexual Что если два существующих столбца имеют одинаковое имя? Как мне обратиться к старому названию столбца?
бродяга
14
Первое решение: df = df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'})изменяет отображаемое имя, но не элементы в базовой структуре данных. Так что если вы попробуете, df['newName1']вы получите ошибку. inplace=TrueНеобходимо избегать этого gotchya.
irritable_phd_syndrom
402

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)
Энди Хейден
источник
56
Ницца. Этот спас мой день:df.rename(columns=lambda x: x.lstrip(), inplace=True)
root-11
2
Аналогично @ root-11 - в моем случае был символ маркера, который не был напечатан в выводе консоли IPython, поэтому мне нужно было удалить не только пробел (полосу), поэтому:t.columns = t.columns.str.replace(r'[^\x00-\x7F]+','')
Red Pea
9
df.rename(columns=lambda x: x.replace(' ', '_'), inplace=True)это драгоценный камень, так что мы можем писать df.Column_1_Nameвместо того, чтобы писать df.loc[:, 'Column 1 Name'].
Маленькие столики Бобби
164

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

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

  • renameМетод был добавлен axisпараметр , который может быть установлен на columnsили 1. Это обновление делает этот метод соответствующим остальному API панд. Он по- прежнему имеет indexи columnsпараметры , но не больше не вынуждены использовать их.
  • set_axisМетод с 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()
Тед Петру
источник
1
Спасибо за Pandas 0.21+ answer- почему-то я пропустил эту часть в части «Что нового» ...
MaxU
1
Похоже, что решение не работает для Pandas 3.6: df.rename ({'$ a': 'a', '$ b': 'b', '$ c': 'c', '$ d': 'd ',' $ e ':' e '}, axis =' columns '). Получает неожиданный аргумент ключевого слова "ось"
Артур Д. Хоулэнд
3
df.columns = ['a', 'b', 'c', 'd', 'e'], похоже, больше не работает, работая с версией 0.22 У меня есть предупреждение о том, что Pandas не позволяет создавать столбцы с помощью новое имя атрибута . как переименовать, если все мои столбцы называются одинаково: /
Набла
Есть ли способ переименовать один, несколько или все столбцы, если вы заранее не знаете названия столбцов, а только их индекс? Спасибо!
tommy.carstensen
это был очень полезный комментарий. например, лямбда-функция ответила на мой вопрос о том, как сделать следующее:(df .groupby(['page',pd.Grouper(key='date',freq='MS')])['clicks'].sum() .unstack(1) .rename(lambda x: x.strftime("%Y-%m"), axis='columns') )
измерить все
131

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

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

ИЛИ

df.rename(columns=lambda x: x.replace('$', ''), inplace=True)
paulo.filip3
источник
1
Это помогает не только в случае OP, но и в общих требованиях. Например: разделить имя столбца по разделителю и использовать одну его часть.
Дипак
77
df.columns = ['a', 'b', 'c', 'd', 'e']

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

М ПОЛ
источник
5
Не модифицируйте df.columns.values, это неправильно. 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)

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

migloo
источник
1
Мне нравится этот подход, но я думаю, что df.columns = ['a', 'b', 'c', 'd', 'e']проще.
Кристофер Пирсон
1
Мне нравится этот способ архивирования старых и новых имен. Мы можем использовать, df.columns.valuesчтобы получить старые имена.
bkowshik
1
Я отображаю табличное представление и копирую столбцы в old_names. Я копирую массив требований в new_names. Тогда используйте dict (zip (old_names, new_names)). Очень элегантное решение.
Мифический
Я часто использую подмножества списков из чего-то вроде: myList = list(df) myList[10:20]и т. Д., Так что это идеально.
Тим Готгетре
Лучше взять старые имена в соответствии с предложением @bkowshik, затем отредактировать их и вставить заново, то есть namez = df.columns.valuesзатем выполнить некоторые правки df.columns = namez.
pauljohn32
34

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

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

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

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

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

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


Настройка 1
Чтобы сосредоточиться на необходимости переименования заменяемых имен столбцов в уже существующий список, я создам новый примерный кадр данных 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. Вместо этого мы можем использовать keysаргумент 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позволяет нам установить индекс в строке, но не соответствует 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
Используйте a 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
piRSquared
источник
Может быть, мы можем добавитьdf.rename(lambda x : x.lstrip('$'),axis=1)
YOBEN_S
Привет @piRSquared, не могли бы вы рассказать о том, как pandas использует лямбда-функцию в решении 5, пожалуйста? Я не совсем понимаю, что вы имеете в виду, когда вы говорите x, игнорируется?
Josmoor98
33

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

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

Датафреймы представляют собой набор 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']]
firelynx
источник
18

Если у вас есть датафрейм, 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)')
andrewwowens
источник
Зачем вам метод переименования? Нечто подобное сработало для меня # df.columns = [row.replace ('$', '') для строки в df.columns]
shantanuo
Я не понимаю часть «вещей». Что я должен заменить? Старые колонны?
Андреа Янни ௫
18

Допустим, это ваш фрейм данных.

введите описание изображения здесь

Вы можете переименовать столбцы двумя способами.

  1. С помощью dataframe.columns=[#list]

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

    введите описание изображения здесь

    Ограничением этого метода является то, что если необходимо изменить один столбец, необходимо передать полный список столбцов. Кроме того, этот метод не применим к индексным меткам. Например, если вы передали это:

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

    Это выдаст ошибку. Несоответствие длины: ожидаемая ось имеет 5 элементов, новые значения имеют 4 элемента.

  2. Другим методом является метод Pandas, rename()который используется для переименования любого индекса, столбца или строки.

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

    введите описание изображения здесь

Точно так же вы можете изменить любые строки или столбцы.

vibhu_singh
источник
17
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]
Александр
источник
2
Вместо того, чтобы lambda col: d[col]вы могли пройти d.get... так это выглядело быdf.columns.map(d.get)
piRSquared
15

Давайте разберемся с переименованием на небольшом примере ...

1. Переименование столбцов с помощью сопоставления:

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. Переименование индекса / Row_Name с использованием сопоставления:

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
Амар Кумар
источник
У наиболее высоко оцененного ответа уже есть такие примеры ...
Итамар Мушкин
14

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

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

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

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

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

Kait
источник
2
Можете ли вы объяснить, как / почему это работает? Это сделает ответ более ценным для будущих читателей.
Дэн Лоу
12

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

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

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

Thodoris P
источник
10

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

df.columns = df.columns.str.slice(1)
Антон Протопопов
источник
1
PS: это более подробный эквивалент df.columns.str[1:]... вероятно, лучше использовать это, это короче и более очевидно.
cs95
9

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

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

Обратите внимание, что этот подход не работает для 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

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

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
источник
6

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

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

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

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)
matthhias
источник
5

В дополнение к уже предоставленному решению вы можете заменить все столбцы во время чтения файла. Мы можем использовать namesи header=0сделать это.

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

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)

В этом случае все имена столбцов будут заменены именами, которые есть в вашем списке.

Stryker
источник
4

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

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')
seeiespi
источник
1
Вариант использования такой функции встречается крайне редко. В большинстве случаев я знаю, что я ищу и что хочу переименовать, я просто назначил / изменил это сам.
cs95
1
@ cs95 Я склонен работать с крупными национальными или международными опросами, где переменные будут иметь кодированные имена переменных, которые начинаются с префиксов в зависимости от вариантов ответа, шкал Лайкерта и ветвления (например, EDU_2913.443, EDU_2913.421, ...). Эта функция была очень полезна для меня при работе с этими типами наборов, я понимаю, если она не для вас :)
seeiespi
4

Переименование столбцов в пандах - это простая задача.

df.rename(columns = {'$a':'a','$b':'b','$c':'c','$d':'d','$e':'e'},inplace = True)
Нирали Хода
источник
2

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

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
источник
2
Хорошей практикой в ​​Stack Overflow является добавление объяснения того, почему ваше решение должно работать или лучше, чем существующие решения. Для получения дополнительной информации прочитайте, как ответить .
Самуэль Лев
Обратите внимание, что для ответа с наивысшей оценкой требуется некоторая форма жесткого кодирования, а для ответа с наихудшей оценкой требуется только описательный и процедурный подход?
Kaustubh J
Есть лучшие (более читаемые) решения, которые также используют регулярные выражения, чем это. Это делает намного больше, чем нужно для простой операции переименования. Существует также опасность того, что шаблон не соответствует ничему, в этом случае вы ничего не сделали для обработки ошибок.
CS95