说我有:
s = 'white male, 2 white females'
并希望"扩展"这个:
'white male, white female, white female'
更完整的案例清单如下:
好像我很接近:
import re
# Do I need boundaries here?
mult = re.compile('two|2 (?P<race>[a-z]+) (?P<gender>(?:fe)?male)s')
# This works:
s = 'white male, 2 white females'
mult.sub(r'\g<race> \g<gender>, \g<race> \g<gender>', s)
# 'white male, white female, white female'
# This fails:
s = 'two hispanic males, 2 hispanic females'
mult.sub(r'\g<race> \g<gender>, \g<race> \g<gender>', s)
# ' , , hispanic males, hispanic female, hispanic female,'
在第二种情况下是什么造成了绊倒?
奖金问题:是否有大熊猫的方法&#39;直接实现此功能的系列而不是使用Series.apply()
?很抱歉修改我的问题并浪费任何人在这里的时间。
例如,在:
s = pd.Series(
['white male',
'white male, white female',
'hispanic male, 2 hispanic females',
'black male, 2 white females'])
是否有比以下更快的路线:
s.apply(lambda x: mult.sub(..., x))
答案 0 :(得分:3)
关于你的&#34;奖金&#34;问题,您可以使用pandas.Series.str.replace
,它是pandas.Series.str
methods的一部分,与正则表达式一起使用:
In [10]: import re
In [11]: import pandas as pd
In [12]: s = pd.Series(
...: ['white male',
...: 'white male, white female',
...: 'hispanic male, 2 hispanic females',
...: 'black male, 2 white females'])
In [13]: mult = re.compile('two|2 (?P<race>[a-z]+) (?P<gender>(?:fe)?male)s')
...:
In [14]: s.str.replace(mult, r'\g<race> \g<gender>, \g<race> \g<gender>')
Out[14]:
0 white male
1 white male, white female
2 hispanic male, hispanic female, hispanic female
3 black male, white female, white female
dtype: object
这些方法是否明显快于我不知道的.apply
。我怀疑你永远不会用object
dtypes快速工作。
注意,如果发现this issue这些方法的速度很慢。我想直到他们认为写出一个Cythonized实现是值得的,那么你可能不会有太多希望。
答案 1 :(得分:1)
IIUC,如果你想要匹配,你需要在two|2
(two|2)
附近放置一下。
import re
mult = re.compile('(two|2) (?P<race>[a-z]+) (?P<gender>(?:fe)?male)s')
s = 'two hispanic males, 2 hispanic females'
mult.sub(r'\g<race> \g<gender>, \g<race> \g<gender>', s)
# 'hispanic male, hispanic male, hispanic female, hispanic female'
答案 2 :(得分:1)
关于你的正则表达式本身,我将使用下面的一个更通用和优化的。
In [14]: mult = re.compile('(?:two|2) ([^,]+)')
In [15]: s = 'two hispanic males, 2 hispanic females'
In [16]: mult.sub(lambda x: x.group(1) + ' ' + x.group(1), s)
Out[16]: 'hispanic males hispanic males, hispanic females hispanic females'
但是关于性能以及使用列表理解将正则表达式应用于Pandas Series
是最好的方法:
In [29]: s = pd.Series(
['white male',
'white male, white female',
'hispanic male, 2 hispanic females',
'black male, 2 white females'])
In [30]: %timeit s.str.replace('(?:two|2) (?P<race>[a-z]+) (?P<gender>(?:fe)?male)s', r'\g<race> \g<gender>, \g<race> \g<gender>')
1000 loops, best of 3: 205 µs per loop
In [31]: %timeit s.apply(lambda x: mult.sub(lambda x: x.group(1) + ' ' + x.group(1), x))
10000 loops, best of 3: 148 µs per loop
In [32]: %timeit [mult.sub(lambda x: x.group(1) + ' ' + x.group(1), i) for i in s]
100000 loops, best of 3: 14.6 µs per loop