【问题标题】:Rename Pandas DataFrame Index重命名 Pandas DataFrame 索引
【发布时间】:2013-11-19 23:42:13
【问题描述】:

我有一个没有标题的 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

【问题讨论】:

  • 我发誓在 2022 年我仍然会像每月 4 次一样查找这个问题。

标签: python pandas dataframe rename


【解决方案1】:

对于单个索引:

 df.index.rename('new_name')

对于多索引:

 df.index.rename(['new_name','new_name2'])

我们也可以在最新的 pandas 中使用它:

rename_axis

【讨论】:

  • 如果你这样做,你只会有一个重命名的索引作为回报,但数据框不会改变。
【解决方案2】:

您可以使用pandas.DataFrameindexcolumns 属性。注意:列表的元素数必须与行数/列数匹配。

#       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

【讨论】:

    【解决方案3】:

    当前选择的答案未提及可用于重命名索引和列级别的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
    

    我们可以像使用 DataFrames 一样使用rename_axis

    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 重命名索引和列中的值。它已被弃用,所以不要这样做

    【讨论】:

    • 你应该把df1 = df.set_index(['state', 'color'], append=True)换成df1.rename_axis(['names', None, 'Colors'])吗?
    • 如果我想将“Nick”重命名为“Nicolas”怎么办?这就是我在谷歌上搜索“重命名熊猫索引”并最终来到这里时所寻找的。编辑:哦,等等,接受的答案确实解释了这一点,起初对我来说并不明显。
    • 很好,这是唯一可以在链式作业中使用的答案!
    • 在重命名索引和列的时候不需要调用两次,你可以用args处理一次:df.rename_axis(index='names', columns='attributes')
    【解决方案4】:

    对于较新的pandas 版本

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

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

    后者是必需的,如果数据框应保留其所有属性。

    【讨论】:

      【解决方案5】:
      df.index.rename('new name', inplace=True)
      

      是唯一为我完成这项工作的人(熊猫 0.22.0)。
      如果没有 inplace=True,在我的情况下没有设置索引的名称。

      【讨论】:

        【解决方案6】:

        如果您想使用相同的映射来重命名列和索引,您可以这样做:

        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)
        

        【讨论】:

          【解决方案7】:

          您也可以使用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
          

          【讨论】:

            【解决方案8】:

            rename 方法采用适用于索引的索引字典。
            您想重命名为索引级别的名称:

            df.index.names = ['Date']
            

            考虑这一点的一个好方法是,列和索引是同一类型的对象(IndexMultiIndex),您可以通过转置将两者互换。

            这有点令人困惑,因为索引名称与列的含义相似,所以这里有更多示例:

            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
            

            可以在索引上看到rename,可以改变value 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
            

            【讨论】:

            • 很好的答案。只是一个温和的提醒,没有"inplace =True"df1.rename 不会真正改变任何事情。
            • @Sarah 为什么你提到的那条神奇的线会做出改变?
            • 就地修改已经存在的 pandas 数据框对象。虽然没有就地的操作使数据框保持不变并返回一个新创建的df。因此,没有重命名必须做这样的事情:df1 = df1.rename....
            • 为什么这个答案在底部?上面的那些都不行。这个答案显然得票最多。
            【解决方案9】:

            在 Pandas 0.13 及更高版本中,索引级别名称是不可变的(类型为 FrozenList)并且不能再直接设置。您必须首先使用Index.rename() 将新的索引级别名称应用于索引,然后使用DataFrame.reindex() 将新索引应用于DataFrame。例子:

            对于 Pandas 版本

            df.index.names = ['Date']
            

            对于 Pandas 版本 >= 0.13

            df = df.reindex(df.index.rename(['Date']))
            

            【讨论】:

            • 不是真的!在我的 Pandas (0.13.1) 版本中,df.index.names = ['foo'] 工作正常!
            • 感谢您注意到@LondonRob - `df.index.names = ['foo']` 也适用于 Pandas 0.14。显然,这只是在我测试时被短暂破坏并包含在内。
            • 直接为indexcolumn 设置名称对我来说都是改变(在Pandas 0.19 上),但不是用这种方法。
            猜你喜欢
            • 2016-02-28
            • 1970-01-01
            • 2019-08-18
            • 2021-05-23
            • 2019-07-21
            • 2013-09-23
            • 2019-01-26
            相关资源
            最近更新 更多