使用 Pandas 替换行中 removing/replacing 字符后的数据帧值

Replacing dataframe values after removing/replacing character in rows using Pandas

我有一个数据框 df_in 像这样:

import pandas as pd
import numpy as np
dic_in = {'A':['aa','bb','cc','dd','ee','ff','gg','uu','xx','yy','zz'],
       'B':['200','200','AA200','AA040',np.nan,'500',np.nan,'0700','900','UKK','200'],
       'C':['UNN','400',np.nan,'AA080','AA800','B',np.nan,'400',np.nan,'500','UKK']}

我的目标是通过以下方式调查列 BC

最终结果应该是这样的:

   # BEFORE #                     # AFTER #
     A      B      C               A      B      C
0   aa    200    UNN          0   aa    200    0.0
1   bb    200    400          1   bb    200    400
2   cc  AA200    NaN          2   cc  20000    0.0
3   dd  AA040  AA080          3   dd   4000   8000
4   ee    NaN  AA800          4   ee    0.0  80000
5   ff    500      B          5   ff    500    0.0
6   gg    NaN    NaN          6   gg    0.0    0.0
7   uu   0700    400          7   uu    700    400
8   xx    900    NaN          8   xx    900    0.0
9   yy    UKK    500          9   yy    0.0    500
10  zz    200    UKK          10  zz    200    0.0

你知道实现这个目标的聪明有效的方法吗?

注意:所有数字实际上都是字符串,应该保持原样。

您可以使用 to_numeric 将非数字替换为 NaN

然后 extract numbers from strings, remove 0 from left by lstrip 并添加 00.

最后 combine_first with fillna 并分配给列:

b = pd.to_numeric(df_in.B, errors='coerce')
c = pd.to_numeric(df_in.C, errors='coerce')

b1 = df_in.B.str.extract('(\d+)', expand=False).str.lstrip('0') + '00'
c1 = df_in.C.str.extract('(\d+)', expand=False).str.lstrip('0') + '00'

df_in.B = b.combine_first(b1).fillna(0)
df_in.C = c.combine_first(c1).fillna(0)
print (df_in)
     A      B      C
0   aa    200      0
1   bb    200    400
2   cc  20000      0
3   dd   4000   8000
4   ee      0  80000
5   ff    500      0
6   gg      0      0
7   uu    700    400
8   xx    900      0
9   yy      0    500
10  zz    200      0

对最后 fillna 字符串 0.0 的一点修改解决方案将所有值转换为字符串(避免一些字符串和一些数值):

b = pd.to_numeric(df_in.B, errors='coerce')
c = pd.to_numeric(df_in.C, errors='coerce')

b1 = df_in.B.str.extract('(\d+)', expand=False).str.lstrip('0') + '00'
c1 = df_in.C.str.extract('(\d+)', expand=False).str.lstrip('0') + '00'

df_in.B = b.combine_first(b1)
df_in.C = c.combine_first(c1)

df_in = df_in.fillna('0.0').astype(str)
print (df_in)
     A      B      C
0   aa  200.0    0.0
1   bb  200.0  400.0
2   cc  20000    0.0
3   dd   4000   8000
4   ee    0.0  80000
5   ff  500.0    0.0
6   gg    0.0    0.0
7   uu  700.0  400.0
8   xx  900.0    0.0
9   yy    0.0  500.0
10  zz  200.0    0.0

假设你的dataframe中的所有值都是字符串(包括NaNs,否则你可以用fillna将它们转换成合适的字符串),你可以使用下面的converter 函数与 applymap 在要转换的两列上。

df = pd.DataFrame(dic_in, dtype=str).fillna('NAN')

converter = lambda x: str(int(x.replace('AA', ''))*100) if 'AA' in x else str(int(x)) if x.isdigit() else '0.0'

df[['B','C']] = df[['B','C']].applymap(converter)

df的内容:

     A      B      C
0   aa    200    0.0
1   bb    200    400
2   cc  20000    0.0
3   dd   4000   8000
4   ee    0.0  80000
5   ff    500    0.0
6   gg    0.0    0.0
7   uu    700    400
8   xx    900    0.0
9   yy    0.0    500
10  zz    200    0.0