python - 根据特定域名仅过滤数据框中的链接
问题描述
我有一个有 5 列的熊猫数据框。link
我需要根据列表中的域名过滤列上的数据框,并重复计算每个进程的行数。假设我有以下数据框:
url_id | link
------------------------------------------------------------------------
1 | http://www.example.com/somepath
2 | http://www.somelink.net/example
3 | http://other.someotherurls.ac.uk/thisissomelink.net&part/sample
4 | http://part.example.com/directory/files
我想根据下面列表中的域名过滤数据框并计算每个结果的数量:
domains = ['example.com', 'other.com', 'somelink.net' , 'sample.com']
以下是预期的输出:
domain | no_of_links
--------------------------
example.com | 2
other.com | 0
somelink.net | 1
sample.com | 0
这是我的代码:
from tld import get_tld
import pandas as pd
def urlparsing(row):
url = row['link']
res = get_tld(url,as_object=True)
return (res.fld)
link = ({"url_id":[1,2,3,4],"link":["http://www.example.com/somepath",
"http://www.somelink.net/example",
"http://other.someotherurls.ac.uk/thisissomelink.net&part/sample",
"http://part.example.com/directory/files"]})
domains = ['example.com', 'other.com', 'somelink.net' , 'sample.com']
df_link = pd.DataFrame(link)
ref_dom = []
for dom in domains:
ddd = df_link[(df_link.apply(lambda row: urlparsing(row), axis=1)).str.contains(dom, regex=False)]
ref_dom.append([dom, len(ddd)])
pd.DataFrame(ref_dom, columns=['domain','no_of_links'])
基本上,我的代码正在运行。但是,当数据框的大小非常大(超过 500 万行),并且域名列表超过十万时,这个过程需要我一天的时间。如果您有其他方法可以使其更快,请告诉我。任何帮助,将不胜感激。谢谢你。
解决方案
您可以使用 df.str 函数的正则表达式和 findall 函数来完成
domains = ['example.com', 'other.com', 'somelink.net' , 'sample.com']
pat = "|".join([f"http[s]?://(?:\w*\.)?({domain})"
for domain in map(lambda x: x.replace(".","\."), domains)])
match = df["link"].str.findall(pat).explode().explode()
match = match[match.str.len()>0]
match.groupby(match).count()
结果
link
example.com 2
somelink.net 1
Name: link, dtype: int64
对于 0.25 之前的熊猫
domains = ['example.com', 'other.com', 'somelink.net' , 'sample.com']
pat = "|".join([f"http[s]?://(?:\w*\.)?({domain})"
for domain in map(lambda x: x.replace(".","\."), domains)])
match = df["link"].str.findall(pat) \
.apply(lambda x: "".join([domain for match in x for domain in match]).strip())
match = match[match.str.len()>0]
match.groupby(match).count()
要获得具有 0 个链接的域,您也可以使用 df 加入所有域的结果
推荐阅读
- contentful - 如何使用 ruby on rails 仅使用 url insted 的 entry-id 获取内容条目?
- java - 令牌“{”上的语法错误,在此令牌切换 (char) 之后需要 SwitchLabels
- amazon-web-services - 如果运行的底层 Powershell 脚本失败,如何使 Ansible 任务失败?
- c# - 不正确的警告将 null 文字或可能的 null 值转换为不可为 null 的类型
- reactjs - 在 rooks 中使用 useDebounce 时如何设置加载为真?
- javascript - 为什么这个 getter 方法在 React 中被调用了多次?
- azure-service-fabric - Service Fabric 中的 Stateless Worker 服务在同一进程中重新启动
- c# - 如何在 C# 的套接字程序中通过网络发送/接收数据
- reactjs - 如何将组件从子组件注入根组件?
- python - 如何在python中检测部分字符串中的部分模式