重命名pandas数据帧中的单个列标题

nat*_*002 154 python rename dataframe pandas

我有一个名为的数据帧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
Run Code Online (Sandbox Code Playgroud)

EdC*_*ica 300

data.rename(columns={'gdp':'log(gdp)'}, inplace=True)
Run Code Online (Sandbox Code Playgroud)

rename它接受一个字典作为一个PARAM演出columns,所以你只是传递一个字典一次入境.

另见相关

  • 这在一个大型数据帧上需要很长时间,所以我相信这会在内存中复制整个数据帧吗? (3认同)
  • 请注意,请注意!如果目标列不存在(拼写名称左右),这将不会有任何错误或警告。 (2认同)

Nic*_*eli 23

list-comprehension如果您需要重命名单个列,则可以使用更快的实现.

df.columns = ['log(gdp)' if x=='gdp' else x for x in df.columns]
Run Code Online (Sandbox Code Playgroud)

如果需要重命名多个列,请使用条件表达式,如:

df.columns = ['log(gdp)' if x=='gdp' else 'cap_mod' if x=='cap' else x for x in df.columns]
Run Code Online (Sandbox Code Playgroud)

或者,使用a构造映射,dictionary并通过将默认值设置为旧名称来执行list-comprehensionwith 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]
Run Code Online (Sandbox Code Playgroud)

时序:

%%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
Run Code Online (Sandbox Code Playgroud)

  • @LelandHepworth 我发现 Pandas 作者是否担心重命名列所需的微秒数值得怀疑。 (6认同)
  • 这有点奇怪,这更快。我假设您使用的问题中的 DataFrame 只有 3 列(y、gdp 和 cap)。如果您使用更多数量的列,列表理解版本是否仍然比使用重命名快 3 倍左右?或者一个版本会比另一个版本快得多吗? (3认同)

cs9*_*s95 11

如何重命名熊猫中的特定列?

从v0.24 +起,要一次重命名一列(或多列),

如果您需要一次重命名所有列,

  • DataFrame.set_axis()的方法axis=1。传递类似列表的序列。选项也可用于就地修改。

renameaxis=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
Run Code Online (Sandbox Code Playgroud)

使用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
Run Code Online (Sandbox Code Playgroud)

(请注意,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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

对于这种特定情况,您可能要使用

df.rename(lambda x: 'log(gdp)' if x == 'gdp' else x, axis=1)
Run Code Online (Sandbox Code Playgroud)

Index.str.replace

replacepython中的字符串方法相似,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
Run Code Online (Sandbox Code Playgroud)

与其他方法相比,此方法的优点是str.replace支持正则表达式(默认情况下启用)。有关更多信息,请参阅文档。


传递一个列表,set_axisaxis=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
Run Code Online (Sandbox Code Playgroud)

注意:在将来的版本中,inplace默认为True

方法链接
为什么选择set_axis已经有一种有效的方式分配列的方式df.columns = ...?如Ted Petrou在[此答案]中所示,(/sf/answers/3283843531/set_axis在尝试链接方法时很有用。

比较

# new for pandas 0.21+
df.some_method1()
  .some_method2()
  .set_axis()
  .some_method3()
Run Code Online (Sandbox Code Playgroud)

# old way
df1 = df.some_method1()
        .some_method2()
df1.columns = columns
df1.some_method3()
Run Code Online (Sandbox Code Playgroud)

前者是更自然和自由流动的语法。


thd*_*oan 7

至少有五种不同的方法可以重命名熊猫中的特定列,我在下面列出了它们以及原始答案的链接。我还对这些方法进行了计时,发现它们的性能大致相同(尽管 YMMV 取决于您的数据集和场景)。下面的试验情况下是列重命名A M N ZA2 M2 N2 Z2在一个数据帧的列AZ含有一百万行。

# 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 - /sf/answers/1383087891/
def method_1():
    df_renamed = df.rename(columns={'A': 'A2', 'M': 'M2', 'N': 'N2', 'Z': 'Z2'})

# Lambda function - /sf/answers/1173924741/
def method_2():
    df_renamed = df.rename(columns=lambda x: x + '2' if x in ['A', 'M', 'N', 'Z'] else x)

# Mapping function - /sf/answers/1383087891/
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 - /sf/answers/4070022771/
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 - /sf/answers/2667075911/
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))
Run Code Online (Sandbox Code Playgroud)

输出:

Method 1: 3.650640267
Method 2: 3.163998427
Method 3: 2.998530871
Method 4: 2.9918436889999995
Method 5: 3.2436501520000007
Run Code Online (Sandbox Code Playgroud)

使用对您来说最直观且最容易在您的应用程序中实现的方法。


小智 5

使用pandas.DataFrame.rename函数。检查此链接以获取说明。

data.rename(columns = {'gdp': 'log(gdp)'}, inplace = True)
Run Code Online (Sandbox Code Playgroud)

如果您打算重命名多个列,那么

data.rename(columns = {'gdp': 'log(gdp)', 'cap': 'log(cap)', ..}, inplace = True)
Run Code Online (Sandbox Code Playgroud)