我正在尝试从任意文本中提取两个值,以不同的方式格式化。这两个值是不同的,我想根据附近的弹簧来区分它们,比如"DDT“和"EEG”。下面是一些如何格式化字符串的示例。
This contains 42.121% DDT and 2.1% EEG
Now with DDT: 12% EEG: 23.2%
47 DDT 22 EEG
EEG N/A DDT 43
5% EEG 20% DDT and more本质上,我需要能够选择它们的标识符前面和后面的两个值。
我一直在两个选择器之间使用|来捕获每个值的两个“案例”,但我遇到了麻烦。我想防止正则表达式在第二个示例行中选择"12% EEG“。我正在尝试使用负的lookaheads和正的lookbehinds,但是不能让它工作。
下面是仅选择ddt的正则表达式
(?<=eeg)(\d{1,3}\.?\d{1,6}).{,10}?ddt|ddt(?!.*eeg).{,10}?(\d{1,3}\.?\d{1,6})这是我得到的最接近的,但它仍然不能正常工作。此版本与“20%DDT”不匹配。
我最初的正则表达式没有使用lookbehinds,但在某些情况下也会失败。
(?:(?:(\d{1,3}\.?\d*)[^(?:eeg)]{0,10}?ddt)|(?:ddt[^(?:eeg)]{0,10}?(\d{1,3}\.?\d*)))我最初的方法无法识别23.2%的EEG字符串,格式如下。"DDT: 12%EEG: 23.2%“
我不确定这种类型的选择器是否可以与regex一起使用,但我想使用regex来向量化这个提取。我有一个函数可以很好地描述这些字符串,但它在大型数据集(大约100万条记录)上非常慢。正则表达式运行得很快,并且很容易应用于向量,这就是我想使用它的原因。如果有其他建议可以用NLP或numpy/pandas函数来解决这个问题,我也愿意接受这些建议。
发布于 2019-05-17 11:31:04
您可以尝试以下操作,至少对于这些情况是这样的:
1/计算出哪个是第一个EEG,哪个是DDT:
In [11]: s.str.extract("(DDT|EEG)")
Out[11]:
0
0 DDT
1 DDT
2 DDT
3 EEG
4 EEG2/取出所有的数字:
In [12]: s.str.extract("(\d+\.?\d*|N/A).*?(\d+\.?\d*|N/A)")
Out[12]:
0 1
0 42.121 2.1
1 12 23.2
2 47 22
3 N/A 43
4 5 20要摆脱N/A,您可以应用to_numeric:
In [13]: res = s.str.extract("(\d+\.?\d*|N/A).*?(\d+\.?\d*|N/A)").apply(pd.to_numeric, errors='coerce', axis=1)
In [14]: res
Out[14]:
0 1
0 42.121 2.1
1 12.000 23.2
2 47.000 22.0
3 NaN 43.0
4 5.000 20.0现在,您必须重新排列这些列,以匹配它们各自的DDT/EEG:
In [15]: pd.DataFrame({
"DDT": res[0].where(s.str.extract("(DDT|EEG)")[0] == 'DDT', res[1]),
"EEG": res[1].where(s.str.extract("(DDT|EEG)")[0] == 'DDT', res[0])
})
Out[15]:
DDT EEG
0 42.121 2.1
1 12.000 23.2
2 47.000 22.0
3 43.000 NaN
4 20.000 5.0这里的s是原始的系列/列:
In [21]: s
Out[21]:
0 This contains 42.121% DDT and 2.1% EEG
1 Now with DDT: 12% EEG: 23.2%
2 47 DDT 22 EEG
3 EEG N/A DDT 43
4 5% EEG 20% DDT and more
dtype: object这假设DDT和EEG都存在,您可能需要NaN出不是这种情况的行(只有DDT/EEG中的一个)...
https://stackoverflow.com/questions/56178766
复制相似问题