Перейменування стовпців у пандах


1822

У мене є DataFrame з використанням панд та міток стовпців, які мені потрібно відредагувати, щоб замінити оригінальні мітки стовпців.

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

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

до

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

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


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

Відповіді:


1826

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

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

302
Чи можна змінити назву заголовка однієї колонки?
ericmjl

112
@ericmjl: припустимо, ви хочете змінити ім'я першої змінної df. Тоді ви можете зробити щось на кшталт:new_columns = df.columns.values; new_columns[0] = 'XX'; df.columns = new_columns
cd98

54
Схоже, ви могли просто зробити df.column.values ​​[0] = 'XX'
RAY

25
Жартую, @RAY - не роби цього. Схоже, що список, сформований незалежно від індексації, зберігає назву стовпця. Виконує гарну роботу, знищуючи назву стовпців для вашого df ...
Мітч Флакс

433
@ericmjl такdf.rename(columns = {'$b':'B'}, inplace = True)
nachocab

2843

ОЗНАЧЕННЯ СПЕЦИФІЧНИХ КОЛОНІВ

Використовуйте 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

2
коли я роблю це за допомогою кадру даних із 6 стовпцями (рамка даних <натисніть Enter>) скорочене представлення: code<class 'pandas.core.frame.DataFrame'> Int64Index: 1000 записів, 0 - 999 Стовпчики даних: BodyMarkdown 1000 ненульових codeробіт , але коли я роблю dataframe.head (), старі назви стовпців знову з’являються.
darKoram

12
Мені стає страшно, SettingWithCopyWarning:коли в цій відповіді я використовую другий фрагмент коду.
Моніка Хеднек

чи є версія цього із заміною регулярного виразу?
denfromufa

@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'].
Столики маленького Бобі


163

Панда 0,21+ відповідь

Було проведено кілька значних оновлень щодо перейменування стовпців у версії 0.21.

  • renameМетод був доданий axisпараметр , який може бути встановлений на columnsабо 1. Це оновлення робить цей метод відповідним решті API панд. У нього все ще є параметри 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()

1
Дякую за те, що Pandas 0.21+ answerя якось пропустив цю частину у частині "Що нового" ...
MaxU

1
Здається, рішення не працює для Pandas 3.6: df.rename ({'$ a': 'a', '$ b': 'b', '$ c': 'c', '$ d': 'd ',' $ e ':' e '}, ось =' стовпці '). Отримує несподіваний аргумент ключового слова "вісь"
Артур Д. Хоуланд

3
df.column = ['a', 'b', 'c', 'd', 'e'], здається, більше не працює, працюючи з версією 0.22 У мене є попередження, що Pandas не дозволяє створювати стовпці через нове ім’я атрибута . як перейменувати, якщо всі мої стовпчики називаються однаковими: /
Nabla

Чи є спосіб перейменувати один, кілька чи всі стовпці, якщо ви не знаєте заздалегідь назву стовпців (ів), а лише їх індекс? Дякую!
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)

1
Цей не лише допомагає у справі ОП, але й у загальних вимогах. Напр .: розділити ім’я стовпця на роздільник і використовувати одну його частину.
Діпак


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як завгодно. Чудово працює, коли вам потрібно перейменувати лише кілька стовпців, щоб виправити неправильні написання, наголоси, видалити спеціальні символи тощо.


1
Мені подобається такий підхід, але я думаю, що df.columns = ['a', 'b', 'c', 'd', 'e']це простіше.
Крістофер Пірсон

1
Мені подобається цей метод стискання старих і нових імен. Ми можемо використовувати df.columns.valuesдля отримання старих імен.
bkowshik

1
Я відображаю табличний вигляд і копіюю стовпці до старих імен. Я копіюю масив вимог у нові імена. Тоді використовуйте dict (zip (old_names, new_names)) Дуже елегантне рішення.
mythicalcoder

Я часто використовую підмножини списків із чогось типу: 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
Використовуйте 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

Можливо, ми можемо додатиdf.rename(lambda x : x.lstrip('$'),axis=1)
YOBEN_S

Привіт @piRSquared, чи зможете ви детальніше пояснити, як панда використовує функцію лямбда в Рішенні 5? Я не зовсім дотримуюся того, що ти маєш на увазі, коли ти кажеш x, що ігнорується?
Josmoor98

33

Назви стовпців і назви серій

Я хотів би трохи пояснити, що відбувається за лаштунками.

Рамки даних - це набір Series.

Серії в свою чергу є розширенням a 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

Тому що панда повторно використовує .nameвже визначені Series.

Багаторівневі назви стовпців

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

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

Це легко досягти, встановивши стовпці для списків, як це:

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

18

Якщо у вас є фрейм даних, df.column скидає все до списку, яким ви можете маніпулювати, а потім перепризначати у свій кадр даних як імена стовпців ...

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 мали функції з найшвидшими часом виконання - хоча ці функції настільки швидкі, що ми порівнюємо округлення .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.column = [row.replace ('$', '') для рядка в df.column]
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'})

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

Так само ви можете змінити будь-які рядки або стовпці.


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.column і додавши смугасті стовпці до df.column.

Натомість ми можемо це зробити акуратно в одному заяві, використовуючи розуміння списку, як показано нижче:

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

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


2
Чи можете ви пояснити, як / чому це працює? Це зробить відповідь більш цінною для майбутніх читачів.
Дан Лоу

12

Справжнє просто використання

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

і він призначить назви стовпців у порядку, який ви їх розмістили


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

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

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)

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)

У цьому випадку всі назви стовпців будуть замінені назви, які ви маєте у своєму списку.


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

1
Випадок використання такої функції є вкрай рідкісним. У більшості випадків я знаю, що шукаю і до чого хочу перейменувати, просто призначив / змінив би сам.
cs95

1
@ cs95 Я прагну працювати з великими національними або міжнародними опитуваннями, де змінні матимуть кодовані імена змінних, які починаються з префіксів залежно від варіантів відповідей, масштабів likert та розгалуження (наприклад, EDU_2913.443, EDU_2913.421, ...). Ця функція була дуже корисною для мене в роботі з тими наборами, я розумію, якщо це не для вас :)
seeiespi

3

Перейменування стовпців у пандах - це легке завдання.

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

2
Додано пояснення щодо переповнення стека, щоб додати пояснення, чому ваше рішення має працювати чи краще, ніж існуючі рішення. Для отримання додаткової інформації читайте як відповісти .
Самуель Liew

Зауважте, як відповідь, що найкраще оцінює, вимагає певної форми жорсткого кодування, а відповідь з найгіршою оцінкою вимагає лише описового та процедурного підходу?
Каустуб J

Є кращі (більш читабельні) рішення, які також використовують регулярний вираз, ніж цей. Це робиться набагато більше, ніж потрібно для простої операції з перейменуванням. Також існує небезпека того, що модель не відповідає нічого, і в цьому випадку ви нічого не зробили для усунення помилок.
cs95
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.