Перейменуйте конкретні стовпчики в пандах


182

У мене викликається кадр даних data. Як мені перейменувати єдиний заголовок стовпця? Наприклад, gdpдо log(gdp)?

data =
    y  gdp  cap
0   1    2    5
1   2    3    9
2   8    7    2
3   3    4    7
4   6    7    7
5   4    8    3
6   8    2    8
7   9    9   10
8   6    6    4
9  10   10    7

7
Очевидно, що це перекриття, але мені було не відразу зрозуміло з "Перейменування стовпців у пандах", що ви можете виділити одиночний елемент стовпця для перейменування. Звичайно, в ретроспективі це очевидно, і якби я копав глибше, я, мабуть, зрозумів би це, але думаю, що це питання / відповідь краще підкреслити це.
jeremiahbuddha

Відповіді:


360
data.rename(columns={'gdp':'log(gdp)'}, inplace=True)

renameПоказує , що він приймає Dict як пари для columnsтак що ви просто пройти Dict з одним записом.

Також дивіться пов'язані


3
На великому фреймі даних потрібно дуже багато часу, тому я вважаю, що це якесь копіювання всього фрейму даних у пам'ять?
elgehelge

1
@elgehelge цього не повинно робити, більшість операцій панд повертає копію, а деякі приймають inplaceпарам. Якщо вона ігнорує цей парам, то це помилка, чи можна робити таймінги з парамером і без нього, також спробуйте щось на кшталт new_df = df.rename(columns={'new_name':'old_name'})і побачити, чи це швидше чи ні
EdChum

1
@ EdChum Дякую Видалення inplaceпарами майже вдвічі збільшило час з 14 секунд до 26 секунд. Але 14 секунд ще досить довгий час, щоб просто змінити заголовок ..
elgehelge

2
лише одна примітка, будьте уважні! якщо цільовий стовпець не існує, (неправильне написання імені тощо), це нічого не зробить без помилок або попередження.
Амір

1
@Quastiat це якось гнітюче, чому деякі з цих простих операцій просто швидше, роблячи розуміння списку. Принципово, хоча, якщо у вас дуже великий df, то це насправді не має значення, якщо ви не перейменовуєте багато стовпців на великий df
EdChum

27

Набагато швидшою реалізацією було б користуватися, list-comprehensionякщо вам потрібно перейменувати один стовпець.

df.columns = ['log(gdp)' if x=='gdp' else x for x in df.columns]

Якщо виникає необхідність перейменувати декілька стовпців, будь-ласка, використовуйте умовні вирази типу:

df.columns = ['log(gdp)' if x=='gdp' else 'cap_mod' if x=='cap' else x for x in df.columns]

Або побудуйте відображення за допомогою a dictionaryта виконайте операцію list-comprehensionз його getдопомогою, встановивши значення за замовчуванням як старе ім'я:

col_dict = {'gdp': 'log(gdp)', 'cap': 'cap_mod'}   ## key→old name, value→new name

df.columns = [col_dict.get(x, x) for x in df.columns]

Терміни:

%%timeit
df.rename(columns={'gdp':'log(gdp)'}, inplace=True)
10000 loops, best of 3: 168 µs per loop

%%timeit
df.columns = ['log(gdp)' if x=='gdp' else x for x in df.columns]
10000 loops, best of 3: 58.5 µs per loop

Я хотів би використовувати цей метод, але, на жаль, він не працює, pd.merge_asof()тому що це вираз :(.
thoan

14

Як перейменувати певний стовпець у пандах?

Від v0.24 +, щоб перейменувати один (або більше) стовпців одночасно,

  • DataFrame.rename()з axis=1або axis='columns'( axisаргумент введено в v0.21.

  • Index.str.replace() для заміни на основі рядків / регулярних виразів.

Якщо вам потрібно перейменувати ВСІ стовпці відразу,

  • DataFrame.set_axis()метод с axis=1. Передайте подібну до списку послідовність Опції також доступні для зміни на місці.

rename з axis=1

df = pd.DataFrame('x', columns=['y', 'gdp', 'cap'], index=range(5))
df

   y gdp cap
0  x   x   x
1  x   x   x
2  x   x   x
3  x   x   x
4  x   x   x

З 0,21+ тепер можна вказати axisпараметр за допомогою rename:

df.rename({'gdp':'log(gdp)'}, axis=1)
# df.rename({'gdp':'log(gdp)'}, axis='columns')
    
   y log(gdp) cap
0  x        x   x
1  x        x   x
2  x        x   x
3  x        x   x
4  x        x   x

(Зверніть увагу, що renameза замовчуванням не встановлено місця, тому вам потрібно буде призначити результат назад .)

Це доповнення було зроблено для покращення узгодженості з рештою API. Новий axisаргумент є аналогом columnsпараметра - вони роблять те ж саме.

df.rename(columns={'gdp': 'log(gdp)'})

   y log(gdp) cap
0  x        x   x
1  x        x   x
2  x        x   x
3  x        x   x
4  x        x   x

rename також приймає зворотний дзвінок, який викликається один раз для кожного стовпця.

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

   y  g  c
0  x  x  x
1  x  x  x
2  x  x  x
3  x  x  x
4  x  x  x

Для цього конкретного сценарію ви хочете використовувати

df.rename(lambda x: 'log(gdp)' if x == 'gdp' else x, axis=1)

Index.str.replace

Аналогічно replaceметоду рядків у python, pandas Index і Series (лише для dtype об'єкта) визначають ("векторизований") str.replaceметод заміни на основі рядків і регулярних виразів .

df.columns = df.columns.str.replace('gdp', 'log(gdp)')
df
 
   y log(gdp) cap
0  x        x   x
1  x        x   x
2  x        x   x
3  x        x   x
4  x        x   x

Перевага цього перед іншими методами полягає в тому, що str.replace підтримує регулярний вираз (включений за замовчуванням). Докладнішу інформацію див. У документах.


Передача списку до set_axis сaxis=1

Дзвоніть set_axisзі списком заголовків. Список повинен бути рівним по довжині стовпцям / розміру індексу. set_axisвимкнює оригінальний DataFrame оригінально, але ви можете вказати йогоinplace=False повернути змінену копію.

df.set_axis(['cap', 'log(gdp)', 'y'], axis=1, inplace=False)
# df.set_axis(['cap', 'log(gdp)', 'y'], axis='columns', inplace=False)

  cap log(gdp)  y
0   x        x  x
1   x        x  x
2   x        x  x
3   x        x  x
4   x        x  x

Примітка. У майбутніх випусках inplace за замовчуванням буде True.

Метод ланцюга
Чому вибирають, set_axisколи у нас вже є ефективний спосіб призначення стовпців df.columns = ...? Як показав Тед Петру у [цій відповіді], ( https://stackoverflow.com/a/46912050/4909087 )set_axis корисний при спробі ланцюгових методів.

Порівняйте

# 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()

Перший - більш природний і вільно текучий синтаксис.


3

Існує щонайменше п’ять різних способів перейменування конкретних стовпців у пандах, і я перелічив їх нижче разом із посиланнями на оригінальні відповіді. Я також приуротив ці методи і виявив їх виконання приблизно однаково (хоча YMMV залежно від вашого набору даних та сценарію). Тест нижче , щоб перейменувати стовпці , A M N Zщоб A2 M2 N2 Z2в dataframe з колонами , Aщоб Zмістить мільйон рядків.

# Import required modules
import numpy as np
import pandas as pd
import timeit

# Create sample data
df = pd.DataFrame(np.random.randint(0,9999,size=(1000000, 26)), columns=list('ABCDEFGHIJKLMNOPQRSTUVWXYZ'))

# Standard way - https://stackoverflow.com/a/19758398/452587
def method_1():
    df_renamed = df.rename(columns={'A': 'A2', 'M': 'M2', 'N': 'N2', 'Z': 'Z2'})

# Lambda function - https://stackoverflow.com/a/16770353/452587
def method_2():
    df_renamed = df.rename(columns=lambda x: x + '2' if x in ['A', 'M', 'N', 'Z'] else x)

# Mapping function - https://stackoverflow.com/a/19758398/452587
def rename_some(x):
    if x=='A' or x=='M' or x=='N' or x=='Z':
        return x + '2'
    return x
def method_3():
    df_renamed = df.rename(columns=rename_some)

# Dictionary comprehension - https://stackoverflow.com/a/58143182/452587
def method_4():
    df_renamed = df.rename(columns={col: col + '2' for col in df.columns[
        np.asarray([i for i, col in enumerate(df.columns) if 'A' in col or 'M' in col or 'N' in col or 'Z' in col])
    ]})

# Dictionary comprehension - https://stackoverflow.com/a/38101084/452587
def method_5():
    df_renamed = df.rename(columns=dict(zip(df[['A', 'M', 'N', 'Z']], ['A2', 'M2', 'N2', 'Z2'])))

print('Method 1:', timeit.timeit(method_1, number=10))
print('Method 2:', timeit.timeit(method_2, number=10))
print('Method 3:', timeit.timeit(method_3, number=10))
print('Method 4:', timeit.timeit(method_4, number=10))
print('Method 5:', timeit.timeit(method_5, number=10))

Вихід:

Method 1: 3.650640267
Method 2: 3.163998427
Method 3: 2.998530871
Method 4: 2.9918436889999995
Method 5: 3.2436501520000007

Скористайтеся найбільш інтуїтивним для вас методом і найпростішим для вас у застосуванні.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.