通过基于“ _”拆分文本来替换熊猫列

时间:2020-10-05 17:05:43

标签: python python-3.x pandas dataframe

我的熊猫数据框如下

import pandas as pd
df = pd.DataFrame({'col':['abcfg_grp_202005', 'abcmn_abc_202009', 'abcgd_xyz_8976', 'abcgd_lmn_1']})
df

    col
0   abcfg_grp_202005
1   abcmn_abc_202009
2   abcgd_xyz_8976
3   abcgd_lmn_1

我想将“ col”替换为“ col”中_之前的第一个实例。如果第三个实例中的_后面有一位数字,则按如下所示将其添加到“ col”的结尾

    col
0   abcfg
1   abcmn
2   abcgd
3   abcgd_1

7 个答案:

答案 0 :(得分:3)

您可以使用df.apply

In [1441]: df['col'] = df.col.str.split('_', expand=True).apply(lambda x: (x[0] + '_' + x[2]) if len(x[2]) == 1 else x[0], axis=1)

In [1442]: df
Out[1442]: 
       col
0    abcfg
1    abcmn
2    abcgd
3  abcgd_1

答案 1 :(得分:2)

放在下划线上,然后添加字符串。在这里,我们可以使用将False乘以字符串返回空字符串以处理条件加法的技巧。支票是1字符串,是数字。

df1 = df['col'].str.split('_', expand=True)
df['col'] = df1[0] + ('_' + df1[2])*(df1[2].str.len().eq(1) & df1[2].str.isdigit())

print(df)

       col
0    abcfg
1    abcmn
2    abcgd
3  abcgd_1

答案 2 :(得分:2)

您可以应用自定义功能。

import pandas as pd
df = pd.DataFrame({'col':['abcfg_grp_202005', 'abcmn_abc_202009', 'abcgd_xyz_8976', 'abcgd_lmn_1']})
def func(x):
    ar = x.split('_')
    if len(ar[2]) == 1 and ar[2].isdigit():
        return ar[0]+"_"+ar[2]
    else:
        return ar[0]
    
df['col'] = df['col'].apply(lambda x: func(x))
df

    col
0   abcfg
1   abcmn
2   abcgd
3   abcgd_1

答案 3 :(得分:1)

这是另一种方法:

df['col'] = np.where(df['col'].str.contains(r'[a-zA-Z0-9]+_[a-zA-Z0-9]+_[0-9]\b', regex=True),
                     df['col'].str.split('_').str[0] + '_' +  df['col'].str.split('_').str[2],
                     df['col'].str.split('_').str[0])
print(df)


       col
0    abcfg
1    abcmn
2    abcgd
3  abcgd_1

答案 4 :(得分:0)

也许不是最优雅的答案,但我建议在这里使用str.replace 两次

df["col"]= df["Team"]
    .str.replace("^([^_]+)_.*?(?!_\d$).{2}$", "\\1")
    .str.replace("_[^_]+(?=_)", "")

第一个正则表达式针对abcfg_grp_202005形式的输入,该输入不以下划线结尾,后跟数字。在这种情况下,我们将剩下abcfg。第二个正则表达式删除中间的下划线(如果它仍然存在的话),只有在abcgd_lmn_1之类的以下划线后跟数字结尾的输入中,这才是正确的。

答案 5 :(得分:0)

尝试一下

for i in range(len(df)):
    x = df.loc[i,"col"].split('_')
    if(len(x[2])==1):
        df.loc[i,"col"] = x[0]+"_"+x[2]
    else:
        df.loc[i,"col"] = x[0]

分割数据,然后检查第二个索引值的长度。如果为1,则将数据拆分为splitd [0] + splited [2]列,如果不是,则将其仅拆分为[0]

答案 6 :(得分:0)

我写了函数。然后,我使用.apply()内置方法将函数应用于每个值。

def editcols(col_value):
    splitted_col_value = col_value.split('_')
    if len(splitted_col_value[2])==1:
        return f'{splitted_col_value[0]}_{splitted_col_value[2]}'
    else:
        return splitted_col_value[0]

df['col'] = df['col'].apply(editcols)

我希望这很清楚。请让我知道它是否有效