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

2302

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

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

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

к

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

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

1
2336

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

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

>>> df.columns = ['a', 'b']
>>> df
   a   b
0  1  10
1  2  20
12
  • 372
    Можно ли изменить имя заголовка одного столбца?
    ericmjl
    26 июня '13 в 17:55
  • 141
    @ericmjl: предположим, вы хотите изменить имя первой переменной df. Тогда вы можете сделать что-то вроде:new_columns = df.columns.values; new_columns[0] = 'XX'; df.columns = new_columns
    cd98
    20 ноя '13 в 14: 182013-11-20 14:18
  • 68
    Похоже, вы могли бы просто сделать df.columns.values ​​[0] = 'XX'
    RAY
    10 марта '14 в 7: 222014-03-10 07:22
  • 28 год
    Шучу, @RAY - не делай этого. Похоже, что список создается независимо от того, какая индексация хранит имя столбца. Отлично справляется с разрушением имен столбцов для вашего df ... 11 марта '14 в 21: 422014-03-11 18:42
  • 537
    @ericmjl да df.rename(columns = {'$b':'B'}, inplace = True) 11 сен '15 в 22:30
3522

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

Используйте 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
 

Начиная с версии 0.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
9
  • 2
    когда я делаю это с фреймом данных из 6 столбцов (dataframe <нажмите Enter>), сокращенное представление: code<class 'pandas.core.frame.DataFrame'> Int64Index: 1000 записей, от 0 до 999 Столбцы данных: BodyMarkdown 1000, ненулевое значение codeработает , но когда я выполняю dataframe.head (), старые имена столбцов снова появляются. 10 сен '12 в 22:39
  • 13
    Я ужасно боюсь, SettingWithCopyWarning:когда использую в этом ответе второй фрагмент кода. 18 авг.
  • есть ли версия с заменой регулярного выражения? 10 ноя '16 в 17:33
  • @lexual Что делать, если два существующих столбца имеют одинаковое имя? Как мне сослаться на старое имя столбца? 09 янв.
  • 16
    Первое решение: df = df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'})изменяет отображаемое имя, но не элементы в базовой структуре данных. Так что если вы попробуете, df['newName1']вы получите ошибку. Это inplace=Trueнеобходимо, чтобы этого не случилось. 14 июл.
458

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)
3
  • 63
    Отлично. Это спасло мне день:df.rename(columns=lambda x: x.lstrip(), inplace=True)
    root-11
    21 окт.
  • 2
    Подобно @ root-11 - в моем случае был символ маркера, который не был напечатан в выводе консоли IPython, поэтому мне нужно было удалить больше, чем просто пробел (полосу), поэтому: t.columns = t.columns.str.replace(r'[^\x00-\x7F]+','') 5 ноя '15 в 6:30
  • 10
    df.rename(columns=lambda x: x.replace(' ', '_'), inplace=True)это драгоценный камень, позволяющий писать, df.Column_1_Nameа не писать df.loc[:, 'Column 1 Name']. 16 дек.
222

Как описано в разделе Работа с текстовыми данными :

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

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

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

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

Примеры для Pandas 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()
5
  • 1
    Спасибо за Pandas 0.21+ answer- как-то я пропустил эту часть в части "что нового" ...
    MaxU
    22 ноя '17 в 13:27
  • 1
    Решение, похоже, не работает для Pandas 3.6: df.rename ({'$ a': 'a', '$ b': 'b', '$ c': 'c', '$ d': 'd ',' $ e ':' e '}, axis =' columns '). Получает неожиданный аргумент ключевого слова "ось" 4 апр '18 в 18:43
  • 3
    df.columns = ['a', 'b', 'c', 'd', 'e'], похоже, больше не работает, работая с версией 0.22. У меня есть предупреждение о том, что Pandas не позволяет создавать столбцы через новое имя атрибута . как переименовать, если все мои столбцы называются одинаково: /
    Nabla
    13 апр '18 в 2:40
  • Есть ли способ переименовать один, несколько или все столбцы, если вы заранее не знаете имя столбца (столбцов), а знаете только их индекс? Спасибо! 17 авг.
  • это был очень полезный комментарий. например, лямбда-функция ответила на мой вопрос о том, как сделать следующее:(df .groupby(['page',pd.Grouper(key='date',freq='MS')])['clicks'].sum() .unstack(1) .rename(lambda x: x.strftime("%Y-%m"), axis='columns') ) 7 дек '18 в 18:32
143

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

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

ИЛИ

df.rename(columns=lambda x: x.replace('$', ''), inplace=True)
1
  • 1
    Это помогает не только в случае OP, но и в общих требованиях. Например: разделить имя столбца разделителем и использовать одну его часть.
    Deepak
    20 ноя '18 в 12: 242018-11-20 12:24
96

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

df.rename(columns={'$a': 'a', '$b': 'b', '$c': 'c', '$d': 'd', '$e': 'e'}, inplace=True)
2
  • 2
    Я сделаю это, так как он, естественно, поддерживается.
    lkahtz
    10 фев в 16:15
  • 1
    намного лучше, чем одобренное решение 24 мая в 10:31
89
df.columns = ['a', 'b', 'c', 'd', 'e']

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

2
73

Использовать:

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усмотрению. Он отлично работает, когда вам нужно переименовать только несколько столбцов, чтобы исправить орфографические ошибки, акценты, удалить специальные символы и т. Д.

5
  • 3
    Мне нравится такой подход, но я думаю, что df.columns = ['a', 'b', 'c', 'd', 'e']он проще. 22 июня '15 в 22:05
  • 2
    Мне нравится этот метод объединения старых и новых имен. Мы можем использовать df.columns.valuesдля получения старых имен. 20 июля '15 в 7: 182015-07-20 07:18
  • 1
    Я отображаю табличное представление и копирую столбцы в old_names. Я копирую массив требований в new_names. Затем используйте dict (zip (old_names, new_names)) Очень элегантное решение. 27 окт.
  • Я часто использую подмножества списков из чего-то вроде: myList = list(df) myList[10:20]и т. Д. - так что это идеально. 12 июл.
  • 1
    Лучше всего взять старые имена, как предложил @bkowshik, затем отредактировать их и снова вставить, то есть namez = df.columns.valuesзатем внести некоторые изменения df.columns = namez. 17 янв.
40

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

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

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

    I have the edited column names stored it in a list, but I don't know how to replace the column names.

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

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

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

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

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

numpy.arrays есть собственность .name.

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

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

Многие ответы здесь говорят о том, что df.columnsатрибут является a, 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

Поскольку Pandas повторно использует .nameуже определенный Series.

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

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

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

Этого легко добиться, задав столбцы списками, например:

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

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

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

     df.rename({0: "x", 1: "y", 2: "z"}, axis='index', inplace =True) # Row name are getting replaced by 'x', 'y', and 'z'.
    
     Output:
    
            new_a  new_b
         x  1       4
         y  2       5
         z  3       6
    
1
  • 1
    На мой взгляд, это, как правило, самый безопасный метод, поскольку он снижает риск ошибки при изменении порядка имен столбцов.
    A Rob4
    12 мая в 6:49
25

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

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

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

  1. С использованием dataframe.columns=[#list]

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

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

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

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

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

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

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

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

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

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

Если у вас есть фрейм данных, 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)')
2
  • Зачем нужен метод переименования? Что-то вроде этого сработало для меня # df.columns = [row.replace ('$', '') для строки в df.columns] 5 сен '15 в 13:19
  • Я не понимаю «вещи». Что мне заменить? Старые колонны? 27 июня '16 в 11: 052016-06-27 11:05
19
df.rename(index=str, columns={'A':'a', 'B':'b'})

pandas.DataFrame.rename

1
  • Объяснение было бы в порядке. 13 фев в 5:53
16

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

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

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

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

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

1
  • 2
    Вы можете объяснить, как / почему это работает? Это сделает ответ более ценным для будущих читателей. 23 нояб.
15

Это очень просто. Просто используйте:

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

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

12

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

df.columns = df.columns.str.slice(1)
1
  • 1
    PS: Это более подробный эквивалент df.columns.str[1:]... вероятно, лучше использовать это, он короче и очевиднее.
    cs95
    25 мая '19 в 16:00
11

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

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
11

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

Обратите внимание, что подходы, описанные в предыдущих ответах, не работают для 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
9

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

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

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

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

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

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

8

Многие функции pandas имеют параметр inplace. При установке значения True преобразование применяется непосредственно к фрейму данных, для которого вы его вызываете. Например:

df = pd.DataFrame({'$a':[1,2], '$b': [3,4]})
df.rename(columns={'$a': 'a'}, inplace=True)
df.columns

>>> Index(['a', '$b'], dtype='object')

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

df = pd.DataFrame({'$a':[1,2], '$b': [3,4]})
df2 = df.rename(columns={'$a': 'a'}, inplace=False)
df.columns
    
>>> Index(['$a', '$b'], dtype='object')

df2.columns

>>> Index(['a', '$b'], dtype='object')

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

6

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

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

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

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
4
  • 2
    Хорошей практикой в ​​Stack Overflow является добавление объяснения того, почему ваше решение должно работать или лучше существующих решений. Для получения дополнительной информации прочтите Как ответить . 11 апр '19 в 23:49
  • Обратите внимание на то, что ответ с наилучшей оценкой требует некоторой формы жесткого кодирования, а ответ с наихудшей оценкой требует только описательного и процедурного подхода? 13 апр '19 в 13:13
  • Есть лучшие (более читаемые) решения, которые также используют регулярное выражение, чем это. Это намного больше, чем нужно для простой операции переименования. Также существует опасность того, что шаблон ничему не соответствует, и в этом случае вы ничего не сделали для обработки ошибок.
    cs95
    25 мая '19 в 3:48
  • Re «Предполагая, что вы можете использовать регулярное выражение» : вы имеете в виду «Предполагая, что вы не можете использовать регулярное выражение» (противоположное)? 13 фев в 5:55
6

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

import re
regex = r"[!\"#$%&'()*+,\-.\/:;<=>[email protected][\\\]^_`{|}~ ]+"
X_trn.columns = X_trn.columns.str.replace(regex, '_', regex=True)
X_tst.columns = X_tst.columns.str.replace(regex, '_', regex=True)
2
  • 2
    FWIW, вы можете просто отслеживать столбцы в отдельном n- мерном списке и передавать в XGBoost только базовый массив / матрицу NumPy, у которой нет заголовков. Таким образом, вы можете называть свои столбцы как хотите, не соглашаясь с тем, что хочет XGBoost. 18 дек.
  • Что же это было ? 13 фев в 6:02
2

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

new_names = ['a', 'b', 'c', 'd', 'e']
new_names_map = {df.columns[i]:new_cols[i] for i in range(len(new_cols))}

df.rename(new_names_map, axis=1, inplace=True)
1

Если вы просто хотите удалить знак «$», используйте приведенный ниже код.

df.columns = pd.Series(df.columns.str.replace("$", ""))