Python - Pandas - 用正则表达式替换字符串| (要么)

Posted

技术标签:

【中文标题】Python - Pandas - 用正则表达式替换字符串| (要么)【英文标题】:Python - Pandas - String Replacement with regex | (OR) 【发布时间】:2021-12-05 17:35:45 【问题描述】:

我有 2 个数据框:

df_bisID = pd.DataFrame('A': ['ID1#ID2', 'ID3#ID4'],
                         'B': ['ID5#ID6', 'ID7#ID8'],
                         'C': ['ID9#ID10', 'ID11#ID12'],
                         'D': ['ID13#ID14', 'ID15#ID16'])

    A       B       C           D
0   ID1#ID2 ID5#ID6 ID9#ID10    ID13#ID14
1   ID3#ID4 ID7#ID8 ID11#ID12   ID15#ID16


df_eliminateID = pd.DataFrame('A': ['ID1', 'ID3', 'ID9', 'ID11'],
                               'B': ['ID5', 'ID7', 'ID13', 'ID15'])

    A    B
0   ID1  ID5
1   ID3  ID7
2   ID9  ID13
3   ID11 ID15

ID 很复杂,由字母数字组成,并且是唯一的('xxxx-xxxxxxxxxx-xxx'+ 兼性后缀 '-xxx-xxx')。我提出了一个简化 ID 的示例。

在 df_bisID 中,我需要删除每列中的 ID 和 # 之一,它分别包含在 df_eliminateID 的 A 或 B 列中。

所以我想用“ID2”替换“ID1#ID2”,用“ID10”替换“ID9#ID10”等。

请注意,它也可能是 'ID2#ID1' 而不是 'ID1#ID2' 并且它使替换条件复杂化,这也是这个问题字符串替换的原因。

我的问题的一个合乎逻辑的解决方案是:

for i in df_eliminateID['A']:
    df_bisID.replace(i+'#|#'+i, '')
for i in df_eliminateID['B']:
    df_bisID.replace(i+'#|#'+i, '')

但最后,我的 df_bisID 是空的,这就是为什么我请求你帮助使用 |正则表达式在我的字符串替换中,我想用 '' 替换 IDX# 或 #IDX 以仅保留其中一个 ID。 或是 |在正则表达式中,也许我没有以正确的方式使用它(是否有排他性或正则表达式?)

提前感谢您的帮助。

编辑:找到解决方案!

我必须将之前在我的数据框中的一些“_”替换为“-”

df.replace('_', '-', regex=True)

如果 regex=False,它不起作用,我不明白为什么(如果有人可以向我解释它会非常酷,我在文档中搜索但在理解方面没有任何收获)

所以我决定测试它是否可以解决这个问题:

dfbis = pd.DataFrame('A': ['ID1#ID2', 'ID3#ID4'],
                      'B': ['ID5#ID6', 'ID7#ID8'],
                      'C': ['ID9#ID20', 'ID21#ID22'],
                      'D': ['ID23#ID24', 'ID25#ID26'])
    A       B       C           D
0   ID1#ID2 ID5#ID6 ID9#ID20  ID23#ID24
1   ID3#ID4 ID7#ID8 ID21#ID22 ID25#ID26

dfdetermine = pd.DataFrame('A': ['ID1', 'ID3', 'ID20', 'ID22'],
                            'B': ['ID5', 'ID7', 'ID23', 'ID25'])

    A    B
0   ID1  ID5
1   ID3  ID7
2   ID20 ID23
3   ID22 ID25

for i in dfdetermine['A'], dfdetermine['B']:
    print(i)
    dfbis = dfbis.replace(i+'#', '', regex=True).replace('#'+i, '', regex=True)

dfbis

    A   B   C    D
0   ID2 ID6 ID9  ID24
1   ID4 ID8 ID21 ID26

我将 ID10+ 更改为 ID20+,否则 ID1 测试会影响结果。

另外,我发现了一些关于字符串替换时间的东西,这启发了我将 IDX# 和 #IDX 替换放入 2 次对 df.replace 的调用中:https://qastack.fr/programming/3411771/best-way-to-replace-multiple-characters-in-a-string

你认为我的程序可以优化吗?

【问题讨论】:

【参考方案1】:

我强烈建议检查可用于 pandas 对象的字符串操作,尤其是 str.replace 函数,我认为这正是您想要的:

for i in df_eliminateID['A']:    
    df_bisID = df_bisID.str.replace(f'i#|#i', '')
for i in df_eliminateID['B']:
    df_bisID = df_bisID.str.replace(f'i#|#i', '')

【讨论】:

str.replace 是一个 pd.Series 函数,整个 DataFrame 的等价物是 replace,我已经在使用但没有成功。【参考方案2】:

您可以修改列索引stack,删除字符串的尾随部分和unstack

(df_bisID.set_axis(pd.MultiIndex.from_product([[0,1],
                                               df_bisID.columns[:2]]),
                   axis=1)
         .stack(level=[0,1])
         .str.split('#').str[0]
         .unstack()
         .reset_index(drop=True)
) 

输出:

      A     B
0   ID1   ID5
1   ID9  ID13
2   ID3   ID7
3  ID11  ID15

【讨论】:

以上是关于Python - Pandas - 用正则表达式替换字符串| (要么)的主要内容,如果未能解决你的问题,请参考以下文章

Python爬虫编程思想(35):用正则表达式搜索替换和分隔字符串

Python 用正则表达式解析数据变成字典。

Python(Pandas) - 我应该在这里使用哪种正则表达式语法?

用于各种日期的 Python/Pandas 正则表达式 [重复]

尝试在 Python / pandas 中使用正则表达式获取子字符串

正则表达式在多个模式之前找到一个数字序列,放入一个新列(Python,Pandas)