我在Pandas系列中有一些串联的文本数据,我想分成3列。
该系列中每个“单元格”中的字符串由以下3部分组成:
[农药名称] [检出量(mg / kg)] [MRL]
我已经探索过使用series.str.split(...
的方法,但是我认为s.str.extract(...
后跟正则表达式捕获组会更有效。但是,我是regex的新手,这被证明是一个巨大的挑战
我尝试使用的解决方案是here。
以下是该系列的一个示例:
df['pesticide_residues_found_in_mg/kg_(mrl)'].head(20)
# 0 Spirotetramat (partial sum) 0.03 (MRL = 2)
# 1 n/a
# 2 n/a
# 3 n/a
# 4 n/a
# 5 n/a
# 6 n/a
# 7 fluopyram 0.01 (MRL = 0.9)
# 8 fenpyrazamine 0.02 (MRL = 3)
# 9 fluopyram 0.05 (MRL = 0.9)
# 10 acetamiprid 0.03 (MRL = 0.2)
# 11 cyprodinil 0.04 (MRL = 1.5)
# 12 fludioxonil 0.02 (MRL = 0.4)
# 13 fenpyrazamine 0.07 (MRL = 3)
# 14 thiacloprid 0.02 (MRL = 0.7)
# 15 acetamiprid 0.04 (MRL = 0.2)
# 16 chlorothalonil 0.03 (MRL = 6)
# 17 cyprodinil 0.1 (MRL = 1.5)
# 18 fludioxonil 0.03 (MRL = 0.4)
# 19 pyrimethanil 0.09 (MRL = 1)
# Name: pesticide_residues_found_in_mg/kg_(mrl), dtype: object
我想从本系列中提取的信息是: 1)农药名称,即第一个单词。 2)检测到的数量(十进制或浮点数)表示一个或两个小数位。 3)MRL,但是我只想捕获数字,而不是括号或“ MRL =”
注意: *农药名称:有时有时是由两部分组成的带连字符的单词,例如“ lambda-cyhalothrin”。 *农药名称:有时该名称后跟括号中的其他信息,例如“(sum)”或“(partial sum)”。 *检测到的数量:虽然该数字通常表示为一个或两个小数位,但是可以想象到,检测到的数量将是一个整数,例如'4'或'20'。
我尝试过的代码:
df['pesticide_residues_found_in_mg/kg_(mrl)'].str.extract(r'(?P<mrl>\(MRL = \d.?\d+?\))')
# This works but captures "MRL = " but if I remove this, it tends to capture the amount detected instead, so "MRL = " identifies the correct number although it's junk I do not want.
df['pesticide_residues_found_in_mg/kg_(mrl)'].str.extract(r'(?P<mrl>\d+\.?\d+?)'
#This doesn't work and results in capturing the amount detected part of the string instead, and only to one decimal place too!
尝试在正则表达式捕获组中尝试检测到的数量可能是: (?P \ d +。?\ d {1,2}?)
我还尝试使用\b
,^
和$
之类的标记来标记单词边界和字符串的开头和结尾,但似乎无法做到这一点要么工作。
我要实现的df新系列的示例:
index - chem_name - amount_detected - mrl
0 - chlorothalonil - 0.03 - 0.1
1 - fenpyrazamine - 0.1 - 3
2 | ddt (sum) | 2.45 | 0
答案 0 :(得分:2)
您在这里。让我知道你的想法。只需使用“字符串提取”并重命名要匹配的列即可。 代码在这里:
import pandas as pd
from pandas.compat import StringIO
RawData="""
id;pesticide_residues_found_in_mg/kg_(mrl)
0;Spirotetramat (partial sum) 0.03 (MRL = 2)
1;n/a
2;n/a
3;n/a
4;n/a
5;n/a
6;n/a
7;fluopyram 0.01 (MRL = 0.9)
8;fenpyrazamine 0.02 (MRL = 3)
9;fluopyram 0.05 (MRL = 0.9)
10;acetamiprid 0.03 (MRL = 0.2)
11;cyprodinil 0.04 (MRL = 1.5)
12;fludioxonil 0.02 (MRL = 0.4)
13;fenpyrazamine 0.07 (MRL = 3)
14;thiacloprid 0.02 (MRL = 0.7)
15;acetamiprid 0.04 (MRL = 0.2)
16;chlorothalonil 0.03 (MRL = 6)
17;cyprodinil 0.1 (MRL = 1.5)
18;fludioxonil 0.03 (MRL = 0.4)
19;pyrimethanil 0.09 (MRL = 1)
"""
df = pd.read_csv(StringIO(RawData), sep=";")
df=df['pesticide_residues_found_in_mg/kg_(mrl)'].str.extract(r'(.*)\s(\d[\d.]*)\s+\(MRL\s*=\s*(\d[\d.]*)\)')
df.rename(columns={0:'pesticide name',1:'amount detected',2:'MRL'},inplace=True)
df.dropna()
以下结果:
pesticide name amount detected MRL
0 Spirotetramat (partial sum) 0.03 2
7 fluopyram 0.01 0.9
8 fenpyrazamine 0.02 3
9 fluopyram 0.05 0.9
10 acetamiprid 0.03 0.2
11 cyprodinil 0.04 1.5
12 fludioxonil 0.02 0.4
13 fenpyrazamine 0.07 3
14 thiacloprid 0.02 0.7
15 acetamiprid 0.04 0.2
16 chlorothalonil 0.03 6
17 cyprodinil 0.1 1.5
18 fludioxonil 0.03 0.4
19 pyrimethanil 0.09 1