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(Pandas) - 我应该在这里使用哪种正则表达式语法?
用于各种日期的 Python/Pandas 正则表达式 [重复]