Переименовать Pandas DataFrame Index

142

У меня есть CSV-файл без заголовка с индексом DateTime. Я хочу переименовать индекс и имя столбца, но с помощью df.rename () переименовывается только имя столбца. Ошибка? Я на версии 0.12.0

In [2]: df = pd.read_csv(r'D:\Data\DataTimeSeries_csv//seriesSM.csv', header=None, parse_dates=[[0]], index_col=[0] )

In [3]: df.head()
Out[3]: 
                   1
0                   
2002-06-18  0.112000
2002-06-22  0.190333
2002-06-26  0.134000
2002-06-30  0.093000
2002-07-04  0.098667

In [4]: df.rename(index={0:'Date'}, columns={1:'SM'}, inplace=True)

In [5]: df.head()
Out[5]: 
                  SM
0                   
2002-06-18  0.112000
2002-06-22  0.190333
2002-06-26  0.134000
2002-06-30  0.093000
2002-07-04  0.098667
Mattijn
источник
5
Для тех, кто придет на этот вопрос в 2017 году, проверьте ответ ниже, чтобы увидеть очень подробное объяснение rename_axisметода.
Тед Петру
3
А для тех, кто не может быть обеспокоен прочтением полного хорошего ответа ниже, быстрое решение df.rename_axis("Date", axis='index', inplace=True)в соответствии с документацией pandas.pydata.org/pandas-docs/stable/generated/… илиdf.index.names = ['Date']
tommy.carstensen

Ответы:

237

renameМетод принимает словарь для индекса , который применяется к индексным значениям .
Вы хотите переименовать в имя уровня индекса:

df.index.names = ['Date']

Хороший способ думать об этом состоит в том, что столбцы и индекс - это один и тот же тип объекта ( Indexили MultiIndex), и вы можете поменять их местами с помощью транспонирования.

Это немного сбивает с толку, так как имена индексов имеют значение, аналогичное столбцам, поэтому вот еще несколько примеров:

In [1]: df = pd.DataFrame([[1, 2, 3], [4, 5 ,6]], columns=list('ABC'))

In [2]: df
Out[2]: 
   A  B  C
0  1  2  3
1  4  5  6

In [3]: df1 = df.set_index('A')

In [4]: df1
Out[4]: 
   B  C
A      
1  2  3
4  5  6

Вы можете увидеть переименование по индексу, которое может изменить значение 1:

In [5]: df1.rename(index={1: 'a'})
Out[5]: 
   B  C
A      
a  2  3
4  5  6

In [6]: df1.rename(columns={'B': 'BB'})
Out[6]: 
   BB  C
A       
1   2  3
4   5  6

Переименовывая имена уровней:

In [7]: df1.index.names = ['index']
        df1.columns.names = ['column']

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

In [8]: df1
Out[8]: 
column  B  C
index       
1       2  3
4       5  6
Энди Хейден
источник
2
Отличный ответ. Просто нежное напоминание о том, что без "inplace =True", на df1.renameсамом деле ничего не изменится.
Сара
63

В текущем выбранном ответе не упоминается rename_axisметод, который можно использовать для переименования уровней индекса и столбца.


Панды имеют некоторую причудливость, когда дело доходит до переименования уровней индекса. Также rename_axisдоступен новый метод DataFrame для изменения имен на уровне индекса.

Давайте посмотрим на DataFrame

df = pd.DataFrame({'age':[30, 2, 12],
                       'color':['blue', 'green', 'red'],
                       'food':['Steak', 'Lamb', 'Mango'],
                       'height':[165, 70, 120],
                       'score':[4.6, 8.3, 9.0],
                       'state':['NY', 'TX', 'FL']},
                       index = ['Jane', 'Nick', 'Aaron'])

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

Этот DataFrame имеет один уровень для каждого индекса строки и столбца. И индекс строки, и столбец не имеют имени. Давайте изменим имя уровня индекса строки на «имена».

df.rename_axis('names')

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

У rename_axisметода также есть возможность изменить имена уровня столбца, изменив axisпараметр:

df.rename_axis('names').rename_axis('attributes', axis='columns')

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

Если вы установите индекс для некоторых столбцов, то имя столбца станет именем нового уровня индекса. Давайте добавим уровни индекса к нашему исходному DataFrame:

df1 = df.set_index(['state', 'color'], append=True)
df1

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

Обратите внимание, что у исходного индекса нет имени. Мы все еще можем использовать, rename_axisно нам нужно передать ему список той же длины, что и количество уровней индекса.

df1.rename_axis(['names', None, 'Colors'])

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

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


Сериалы работают аналогично, но с некоторыми отличиями

Давайте создадим серию с тремя уровнями индекса

s = df.set_index(['state', 'color'], append=True)['food']
s

       state  color
Jane   NY     blue     Steak
Nick   TX     green     Lamb
Aaron  FL     red      Mango
Name: food, dtype: object

Мы можем использовать rename_axisаналогично тому, как мы сделали с DataFrames

s.rename_axis(['Names','States','Colors'])

Names  States  Colors
Jane   NY      blue      Steak
Nick   TX      green      Lamb
Aaron  FL      red       Mango
Name: food, dtype: object

Обратите внимание, что под серией есть дополнительный фрагмент метаданных Name. При создании Series из DataFrame этому атрибуту присваивается имя столбца.

Мы можем передать имя строки renameметоду, чтобы изменить его

s.rename('FOOOOOD')

       state  color
Jane   NY     blue     Steak
Nick   TX     green     Lamb
Aaron  FL     red      Mango
Name: FOOOOOD, dtype: object

У DataFrames нет этого атрибута, и infact вызовет исключение, если используется так

df.rename('my dataframe')
TypeError: 'str' object is not callable

До появления панды 0.21 вы могли бы использовать rename_axisдля переименования значений в индексе и столбцах. Это устарело, так что не делайте этого

Тед Петру
источник
1
Вы должны поменяться df1 = df.set_index(['state', 'color'], append=True)с df1.rename_axis(['names', None, 'Colors'])?
Салхин
Что если я захочу переименовать «Ника» в «Николя»? Это было то, что я искал, когда я погуглил «переименовать индекс панд» и оказался здесь. РЕДАКТИРОВАТЬ: Ой, подождите, принятый ответ действительно объясняет это, это просто не было очевидно для меня вначале.
Бен Фармер
Отлично, это единственный ответ, который можно использовать в цепочечных заданиях!
Ians
19

Для новых pandasверсий

df.index = df.index.rename('new name')

или

df.index.rename('new name', inplace=True)

Последнее требуется, если фрейм данных должен сохранить все свои свойства.

Серж Строобандт
источник
18

В версии Pandas 0.13 и выше имена уровня индекса являются неизменяемыми (тип FrozenList) и больше не могут быть установлены напрямую. Сначала необходимо использовать, Index.rename()чтобы применить новые имена уровня индекса к Индексу, а затем использовать, DataFrame.reindex()чтобы применить новый индекс к DataFrame. Примеры:

Для версии Pandas <0,13

df.index.names = ['Date']

Для версии Pandas> = 0,13

df = df.reindex(df.index.rename(['Date']))
Дэвид Смит
источник
9
Не правда! В моей версии Pandas (0.13.1) df.index.names = ['foo'] работает отлично!
LondonRob
5
Спасибо, что заметили, что @LondonRob - `df.index.names = ['foo']` также работает для меня с Pandas 0.14. Видимо, это было сломано только на короткое время и включено, когда я проверял это.
Дэвид Смит
1
Установка имен для одного indexили columnсразу меняется как для меня (на Pandas 0.19), но не с этим методом.
FooBar
8

Вы также можете использовать Index.set_namesследующее:

In [25]: x = pd.DataFrame({'year':[1,1,1,1,2,2,2,2],
   ....:                   'country':['A','A','B','B','A','A','B','B'],
   ....:                   'prod':[1,2,1,2,1,2,1,2],
   ....:                   'val':[10,20,15,25,20,30,25,35]})

In [26]: x = x.set_index(['year','country','prod']).squeeze()

In [27]: x
Out[27]: 
year  country  prod
1     A        1       10
               2       20
      B        1       15
               2       25
2     A        1       20
               2       30
      B        1       25
               2       35
Name: val, dtype: int64
In [28]: x.index = x.index.set_names('foo', level=1)

In [29]: x
Out[29]: 
year  foo  prod
1     A    1       10
           2       20
      B    1       15
           2       25
2     A    1       20
           2       30
      B    1       25
           2       35
Name: val, dtype: int64
LondonRob
источник
2
Может ли это работать на multiIndex? MultiIndex(levels=[['A', 'B', 'C', 'D', 'E', 'F'], ['Y', 'Z']], labels=[[0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5], [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]], names=['Portfolio', None])Можно ли переименовать Noneв measures?
Ctrl-Alt-Delete
2

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

mapping = {0:'Date', 1:'SM'}
df.index.names = list(map(lambda name: mapping.get(name, name), df.index.names))
df.rename(columns=mapping, inplace=True)
данио
источник
0
df.index.rename('new name', inplace=True)

Это единственный, кто выполняет эту работу за меня (панды 0.22.0).
Без inplace = True, имя индекса не устанавливается в моем случае.

Ян Х.
источник
0

Вы можете использовать indexи columnsатрибуты pandas.DataFrame. ПРИМЕЧАНИЕ: количество элементов списка должно соответствовать количеству строк / столбцов.

#       A   B   C
# ONE   11  12  13
# TWO   21  22  23
# THREE 31  32  33

df.index = [1, 2, 3]
df.columns = ['a', 'b', 'c']
print(df)

#     a   b   c
# 1  11  12  13
# 2  21  22  23
# 3  31  32  33
nucsit026
источник