我需要从pandas df中提取子串,并将它们放入新列中。 我看起来像这样的字符串:
hj_yu_fb824_as22
jk_yu_fb638
我需要提取:
fb824
fb638
此外,它们的子串可以位于数据帧的两个独立列中(尽管只出现一次),因为df看起来像:
col1 col2
mf_lp_gn817_ml46 d_nb_05340.gif
desktop_300x250_mf mf_lp_fb824_ml46.html
desktop_300x250_mf dd_lp_ig805.html
desktop_728x90_mf mf_lp_fb824_ml46.html
我想获得类似的东西:
col1 col2 col3
mf_lp_gn817_ml46 d_nb_05340.gif gn817
desktop_300x250_mf mf_lp_fb824_ml46.html fb824
desktop_300x250_mf dd_lp_ig805.html ig805
desktop_728x90_mf mf_lp_fb824_ml46.html fb824
所以子字符串看起来像:
1)开头有两个小写字符,后跟3个数字 2)两个''之间或只有一个'',或'_'和'。'之间。别的什么
我想出了:
\_([^()]*)\_
但它只是匹配“_”之间的任何内容,无论上述模式如何。
此外,如何有效地将正则表达式应用于pandas数据帧?
这是可重现的数据框:
df = DataFrame({'col1': {0: 'mf_lp_gn817_ml46',
1: 'desktop_300x250_mf',
2: 'desktop_300x250_mf',
3: 'desktop_728x90_mf'},
'col2': {0: 'd_nb_05340.gif ',
1: 'mf_lp_fb824_ml46.html ',
2: 'dd_lp_ig805.html ',
3: 'mf_lp_fb824_ml46.html '},
'col3': {0: 'gn817', 1: 'fb824', 2: 'ig805', 3: 'fb824'}})
答案 0 :(得分:2)
可能需要更多输入字符串,但对于上面的字符串,您可以提出以下正则表达式:
_([a-z]{2}[0-9]{3})[_.]
# this is an underscore
# followed by exactly 2 letters and 3 digits
# followed by an underscore or a dot
# the whole match is captured to group1
对于您的上述字符串,这将是:
mf_lp_gn817_ml46 d_nb_05340.gif -> gn817
desktop_300x250_mf mf_lp_fb824_ml46.html -> fb824
desktop_300x250_mf dd_lp_ig805.html -> ig805
desktop_728x90_mf mf_lp_fb824_ml46.html -> fb824
要将其应用于您的DataFrame,请参阅以下代码:
import pandas as pd
from pandas import DataFrame
import re
df = DataFrame({'col1': {0: 'mf_lp_gn817_ml46',
1: 'desktop_300x250_mf',
2: 'desktop_300x250_mf',
3: 'desktop_728x90_mf'},
'col2': {0: 'd_nb_05340.gif ',
1: 'mf_lp_fb824_ml46.html ',
2: 'dd_lp_ig805.html ',
3: 'mf_lp_fb824_ml46.html '}})
regex = r'_([a-z]{2}[0-9]{3})[_.]'
for index, row in df.iterrows():
for column in row.keys():
m = re.search(regex, row[column])
if m is not None:
df.ix[index, 'col3'] = m.group(1)
答案 1 :(得分:0)
我从https://stackoverflow.com/users/1231450/jan的答案中学到了很多,非常优雅。我也遇到了这个额外的步骤,并认为我会做出贡献。
保存生成的正则表达式对象以便重用更有效(如果您执行的操作不止一些)。 见:https://docs.python.org/3.5/library/re.html 6.2.2。模块内容
prog = re.compile(r'_([a-z]{2}[0-9]{3})[_.]')
for index, row in df.iterrows():
for column in row.keys():
m = prog.search(row[column])
if m is not None:
df.ix[index, 'col3'] = m.group(1)