重命名并运行基于列关键字的计算

rename and run calculations based on column keywords

提问人:byc 提问时间:10/19/2023 更新时间:10/19/2023 访问量:149

问:

我有一个大型数据帧,我想在其中重命名并基于列标签运行不同的计算。我的数据帧如下所示

toy_df = pd.DataFrame(data=np.random.rand(50,8), columns = ('A_distance_km', 'A_costinUSD', 'B_distance_km' ,'B_costinUSD', 'C_distance_km', 'C_costinUSD', 'D_dosomething', 'D_dosomethingelse'))

我编写了这个函数来将所有距离列转换为米,并将所有costinUSD转换为costinEUR。但是我遇到了.我应该如何解决它的任何想法?AttributeError: 'str' object has no attribute 'str'

def convert_units(df):
    for col in df.columns:
        if col.str.contains("distance"):
            col = col + '_convert_m'
            df[col] = df[col]*1000
        elif col.str.contains("costinUSD"):
            df[col] = df[col]*0.95
        else:
            return col
    return df
Python pandas 字符串 数据帧

评论

0赞 Mortz 10/19/2023
for col in df.columns循环列名 - 在您可能想要的 / 中ifelifdf[col].str.contains...
0赞 RomanPerekhrest 10/19/2023
return col在您的情况下可能不是预期/可取的
0赞 byc 10/19/2023
@Mortz遗憾的是,我在使用 .ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()df[col].str.contains
0赞 byc 10/19/2023
@RomanPerekhrest我也尝试删除,但仍然有相同的属性错误......return col

答:

1赞 Timeless 10/19/2023 #1

这是因为保存标签/字符串,而不是 Series(具有 contains 方法)。

我想你想重命名列(同时保持顺序?)并进行条件计算。如果是这样,按照你的方法,你可以这样修复你的代码:

def convert_units(df):
    for col in df.columns:
        pos_col = df.columns.get_loc(col)
        if "distance" in col:
            df.insert(pos_col, col + "_convert_m", df.pop(col)*1000)
        elif "costinUSD" in col:
            df.insert(pos_col, col, df.pop(col)*0.95)

    return df
    
out = toy_df.pipe(convert_units) # or convert_units(toy_df)

输出:

print(out) # with `toy_df` seeded at 0

    A_distance_km_convert_m  A_costinUSD  ...  D_dosomething  D_dosomethingelse
0                    548.81         0.68  ...           0.44               0.89
1                    963.66         0.36  ...           0.07               0.09
2                     20.22         0.79  ...           0.46               0.78
3                    118.27         0.61  ...           0.26               0.77
4                    456.15         0.54  ...           0.94               0.68
..                      ...          ...  ...            ...                ...
45                   187.13         0.86  ...           0.72               0.40
46                   904.04         0.66  ...           0.24               0.16
47                   796.39         0.91  ...           0.95               0.58
48                   820.77         0.86  ...           0.06               0.42
49                   258.68         0.81  ...           0.02               0.19

[50 rows x 8 columns]

评论

0赞 byc 10/19/2023
谢谢@RomanPerekhrest @Timeless!一个相关的问题 - 乘法在这些列中工作正常,但除法也有效吗?
1赞 Timeless 10/19/2023
是的,您可以稍微调整一下 @RomanPerekhrest 的代码并使用 .df[col] /= 1000
2赞 RomanPerekhrest 10/19/2023 #2

df.columns表示字符串序列(作为列名),这意味着基本行为。
若要有选择地重命名和重新计算具有单个遍历的列,请使用以下方法:
str

def convert_units(df):
    rename_map = {}  # for columns to rename

    for col in df.columns:
        if "distance" in col:
            rename_map[col] = col + '_convert_m'
            df[col] *= 1000
        elif "costinUSD" in col:
            df[col] *= 0.95
    df = df.rename(columns=rename_map)

    return df

toy_df = convert_units(toy_df)
print(toy_df)

   A_distance_km_convert_m  A_costinUSD  B_distance_km_convert_m  B_costinUSD  C_distance_km_convert_m  C_costinUSD  D_dosomething  D_dosomethingelse
0                399.410277     0.127763               944.464091     0.599890               984.958983     0.431538       0.726368           0.603368
1                596.215569     0.834464                99.491461     0.161833               179.692729     0.327060       0.215208           0.288471
2                518.543479     0.451908               613.992588     0.112528               173.772711     0.554944       0.062708           0.019648
3                863.403168     0.469870               773.790350     0.686386               750.875558     0.241806       0.849428           0.988271
4                148.359791     0.832264               366.891421     0.077060               991.598502     0.884995       0.196801           0.302110
5                496.825790     0.509180               997.418855     0.455643               509.158725     0.666080       0.984209           0.915218
...