【问题标题】:String replacement of column names in pythonpython中列名的字符串替换
【发布时间】:2021-09-12 01:29:22
【问题描述】:

我有一个包含 15 列的数据框 df(见下文)

A_phase_1,A_phase_2,A_phase_3,A_phase_4,A_phase_5,B_phase_1,B_phase_2,B_phase_3,C_phase_233@,B_phase_5,B_phase_5,B_phase_5 ,C_phase_3,C_phase_4,C_phase_5.

同时使用phase_1 保留列,例如=A_phase_1, B_phase_1 and C_phase_1

我想以编程方式执行以下操作:

  1. 删除包含phase_2即=A_phase_2,B_phase_2,C_phase_2的列

  2. 将剩余的列名phase_n 替换为phase_n-1。例如,

所有phase_3变成phase_2

phase_4 --> phase_3;

phase_5 --> phase_4

所以想要的输出应该是这样的:

A_phase_1,A_phase_2,A_phase_3,A_phase_4,

B_phase_1,B_phase_2,B_phase_3,B_phase_4,

C_phase_1,C_phase_2,C_phase_3,C_phase_4.

提前致谢!

@seaBean 我收到了这个错误

【问题讨论】:

标签: python pandas replace apply


【解决方案1】:

您可以使用.filter() 过滤要删除的列。然后,使用 df.columns.map() 和 lambda 函数重命名列,如下:

df = df.drop(df.filter(like='phase_2').columns, axis=1)

df.columns = df.columns.map(lambda x: (x[:-1] + str(int(x[-1]) -1)) if (x[-1].isdigit() and (int(x[-1]) > 1)) else x)

输入:

print(df)

  A_phase_1 A_phase_2 A_phase_3 A_phase_4 A_phase_5 B_phase_1 B_phase_2 B_phase_3 B_phase_4 B_phase_5 C_phase_1 C_phase_2 C_phase_3 C_phase_4 C_phase_5 X_phase_t
0        A1        A2        A3        A4        A5        B1        B2        B3        B4        B5        C1        C2        C3        C4        C5        Xt

输出:

print(df)

  A_phase_1 A_phase_2 A_phase_3 A_phase_4 B_phase_1 B_phase_2 B_phase_3 B_phase_4 C_phase_1 C_phase_2 C_phase_3 C_phase_4 X_phase_t
0        A1        A3        A4        A5        B1        B3        B4        B5        C1        C3        C4        C5        Xt

【讨论】:

  • 我需要多使用 .filter,你的解决方案上的 .drop 行非常简洁易读!
  • @ClayShwery 是的,使用各种方法过滤列是一个非常方便的功能。它也支持正则表达式过滤!真的很强大。
  • @seaBean,第二个代码(有 lambda 函数返回错误-valueError: invalid literal for int() with base 10: 't'
  • @SeaBean,我已将错误的屏幕截图添加到初始帖子中。谢谢
  • @RickyTricky 您的实际列名有一些以“t”而不是数字结尾的列?
【解决方案2】:
# 1.) delete phase 2 cols 
#    more precisely, keep only the other columns
df = df[[col for col in df.columns if col[-1]!='2']]
# This next could be done inline but keeping it separate here
rename_dict = {col:col[:-1]+str(int(col[-1])-1) for col in df.columns if col[-1] in ['3','4','5']}
df.rename(columns=rename_dict,inplace=True)

【讨论】:

    【解决方案3】:
    from pandas import DataFrame
    from itertools import product
    
    def ren(col):
        prefix, sufix = col.rsplit('_', maxsplit=1)
        sufix = int(sufix)
        return f'{prefix}_{max(sufix-1, 1)}'
    
    # some dummy df
    df = DataFrame({f'{letter}_phase_{n}':[i, i, i] 
                    for i, (letter, n) in 
                    enumerate(product('ABC', range(1, 6)), start=1)})
    
    df = df.drop(df.filter(like='phase_2').columns, axis=1)
    # df = df.drop([f'{letter}_phase_2' for letter in 'ABC'], axis=1) # alternative
    df = df.rename(mapper=ren, axis=1)
    print(df)
    

    【讨论】:

    • 这只适用于你的虚拟 df,但不适用于我的 df
    • @RickyTricky,f从接受的答案中的 cmets 和您添加的屏幕截图错误中,很明显您的问题中的信息不正确 - 列名以 t 结尾。下次不要浪费人们试图帮助你的时间 - make good reproducible pandas examples
    猜你喜欢
    • 2021-05-21
    • 2019-01-30
    • 2010-10-20
    • 2013-02-17
    • 2019-02-26
    • 1970-01-01
    • 1970-01-01
    • 2019-10-01
    • 2013-06-20
    相关资源
    最近更新 更多