我想使用矢量化操作来改进我的Pandas代码。因此,假设我有一个简单的DataFrame,它有一个可能包含urls的文本列。
Column1
0 hello http://www.google.com
1 bye www.mail.com www.docs.google.com/index
...
此时,我正在迭代这些行,并应用以下替换:
s = re.sub('https*://[\w\.]+\.com[\w=*/\-]+|https*://[\w\.]+\.com|[\w\.]+\.com/[\w/\-]+',lambda x: re.findall('(?<=\://)[\w\.]+\.com|[\w\.]+\.com', x.group())[0], s)
预期输出应为:
Column1
0 hello google.com
1 bye mail.com docs.google.com
...
是否有可能在整个系列中同时执行此操作?
发布于 2018-05-31 17:31:44
在多次尝试错误之后,我找到了一个有效的解决方案。它远不是很有效率,但目前我需要一些有效的东西,我会在不久的将来尝试优化它,并更新帖子。
def replace_url(text):
pat = '(([https?://]*[www\.]*)([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?)'
urls = re.findall(pat, text)
for url in urls:
text = text.replace(url[0], url[2])
return text
df['Column1'] = df['Column1'].apply(replace_url)
感谢@killerT2333,他给了我一些如何进行的直觉。
发布于 2018-05-28 23:28:47
在您给出的示例中,您可以使用str.replace()
df['column1'] = df['column1'].str.replace('http|https|://|www.','') \
#replace some patterm by nothing
.str.replace('.com/[\w/\-]+','.com')
# replace specific pattern by other specific pattern
然后,如果它不能满足您的所有条件,您可以添加更多具有所需条件的.str.replace()
编辑:在查看documentation of Series.str.replace之后,它等同于re.sub()
,因此您可以这样做:
df['column1'] = df['column1'].str.replace('https*://[\w\.]+\.com[\w=*/\-]+|https*://[\w\.]+\.com|[\w\.]+\.com/[\w/\-]+',
lambda x: re.findall('(?<=\://)[\w\.]+\.com|[\w\.]+\.com', x.group())[0])
在内部,参数与您问题的re.sub()
中的参数相同。但你并没有真正得到你期望的输出,你保留了“www.”有了这个。
发布于 2018-05-28 23:31:21
保留您的逻辑和用于替换的代码,您可以这样做:
import pandas as pd
import re
d = {'Column1': ["hello http://www.google.com", "bye www.mail.com www.docs.google.com/index"]}
df = pd.DataFrame(data=d)
f = lambda s : re.sub('https*://[\w\.]+\.com[\w=*/\-]+|https*://[\w\.]+\.com|[\w\.]+\.com/[\w/\-]+',lambda x: re.findall('(?<=\://)[\w\.]+\.com|[\w\.]+\.com', x.group())[0], s)
print(df["Column1"].apply(f))
https://stackoverflow.com/questions/50568513
复制相似问题