我的数据集中有一列具有以下格式:
'XX4H30M'
我需要将这些序列中的数字提取到两列(' H'和' M)。
如果格式完全如上所述,则以下内容符合我的要求:
d3 = df.colname.str.extract('([0-9])([0-9])', expand=True)
d3.columns = ['H', 'M']
df = pd.concat([df, d3])
但是,本系列中的大量单元格只包含
'XX45M'
或XX3H
有没有办法可选地提取这些模式以将它们插入到全局df中?
对于一组具体的例子:
df = pd.DataFrame({'A': ['XX1H30M', 'XX45M', 'XX2H'])
最终会成为
Out:
A H M
0 XX1H30M 1 30
1 XX45M 0 45
2 XX2H 2 0
答案 0 :(得分:2)
您可以尝试这样的事情:
df.assign(H=df.A.str.extract('([\d]+)H', expand=False),
M=df.A.str.extract('([\d]+)M', expand=False)).fillna(0)
输出:
A H M
0 XX1H30M 1 30
1 XX45M 0 45
2 XX2H 2 0
答案 1 :(得分:2)
在一个步骤中提取H
和M
的另一个选项,此处使用(?:(?P<H>\d+)H)?(?:(?P<M>\d+)M)?
来捕获H
和M
作为命名组;为了避免由于两个组都是可选的而匹配空字符串,请在模式的开头添加一个前瞻断言(?=\d+H|\d+M)
:
df = pd.DataFrame({'A': ['XXX1H30M', 'XXX45M', 'XXX2H', 'XXX']})
df.A.str.extract(r'(?=\d+H|\d+M)(?:(?P<H>\d+)H)?(?:(?P<M>\d+)M)?', expand=True).fillna(0)
# H M
#0 1 30
#1 0 45
#2 2 0
#3 0 0
与单独提取相比,这有点快:
df = pd.concat([df] * 10000)
%timeit pd.concat([df, df.A.str.extract(r'(?=\d+H|\d+M)(?:(?P<H>\d+)H)?(?:(?P<M>\d+)M)?', expand=False).fillna(0)], axis=1)
#10 loops, best of 3: 83.9 ms per loop
%timeit df.assign(H=df.A.str.extract('([\d]+)H', expand=False), M=df.A.str.extract('([\d]+)M', expand=False)).fillna(0)
#10 loops, best of 3: 130 ms per loop