重命名 Pandas DataFrame 索引
- 2025-01-21 09:01:00
- admin 原创
- 78
问题描述:
我有一个没有标题的 csv 文件,带有 DateTime 索引。我想重命名索引和列名,但使用 df.rename() 只会重命名列名。有错误?我使用的是 0.12.0 版本
In [2]: df = pd.read_csv(r'D:DataDataTimeSeries_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
解决方案 1:
该方法采用适用于索引值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:
当前选定的答案没有提到rename_axis
可用于重命名索引和列级别的方法。
Pandas 在重命名索引级别时有一些怪癖。还有一种新的 DataFrame 方法rename_axis
可用于更改索引级别名称。
让我们看一下 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
请注意,Series 下方有一个名为 的额外元数据Name
。从 DataFrame 创建 Series 时,此属性设置为列名。
我们可以将字符串名称传递给rename
方法来改变它
s.rename('FOOOOOD')
state color
Jane NY blue Steak
Nick TX green Lamb
Aaron FL red Mango
Name: FOOOOOD, dtype: object
DataFrames 没有此属性,如果这样使用,实际上会引发异常
df.rename('my dataframe')
TypeError: 'str' object is not callable
在 pandas 0.21 之前,您可以使用rename_axis
重命名索引和列中的值。它已被弃用,所以不要这样做
解决方案 3:
对于较新pandas
版本
df.index = df.index.rename('new name')
或者
df.index.rename('new name', inplace=True)
如果数据框要保留其所有属性,则需要后者。
解决方案 4:
在 Pandas 0.13 及更高版本中,索引级别名称是不可变的(类型FrozenList
),并且不能再直接设置。您必须首先使用Index.rename()
将新的索引级别名称应用于 Index,然后使用DataFrame.reindex()
将新索引应用于 DataFrame。示例:
对于 Pandas 版本 <0.13
df.index.names = ['Date']
对于 Pandas 版本 >= 0.13
df = df.reindex(df.index.rename(['Date']))
解决方案 5:
对于单一索引:
df.index.rename('new_name')
对于多索引:
df.index.rename(['new_name','new_name2'])
我们也可以在最新的熊猫中使用它:
重命名轴
解决方案 6:
您还可以按如下方式使用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
解决方案 7:
您可以使用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
解决方案 8:
如果您想使用相同的映射来重命名列和索引,您可以执行以下操作:
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)
解决方案 9:
df.index.rename('new name', inplace=True)
是唯一一款可以帮我完成这项工作的产品(pandas 0.22.0)。
如果没有 inplace=True,则索引名称在我的情况下不会设置。