我有一个数据框,其中包含“链接”列,其中包含数千篇在线文章的 URL。每个观察都有一个 URL。
urls_list = ['http://www.ajc.com/news/world/atlan...',
'http://www.seattletimes.com/sports/...',
'https://www.cjr.org/q_and_a/washing...',
'https://www.washingtonpost.com/grap...',
'https://www.nytimes.com/2017/09/01/...',
'http://www.oregonlive.com/silicon-f...']
df = pd.DataFrame(urls_list,columns=['Links'])
我还有一个字典,其中包含作为键的出版物名称和作为值的域名。
urls_dict = dict({'Atlanta Journal-Constitution':'ajc.com',
'The Washington Post':'washingtonpost.com',
'The New York Times':'nytimes.com'})
我想过滤数据帧以仅获取“链接”列包含字典值中的域的观察结果,同时同时在字典键中分配出版物名称到新专栏“出版物”。我设想的是使用下面的代码创建“发布”列,然后从该列中删除“无”以在事后过滤数据帧。
pub_list = []
for row in df['Links']:
for k,v in urls_dict.items():
if row.find(v) > -1:
publication = k
else:
publication = None
pub_list.append(publication)
但是,我得到的返回列表 pub_list
- 虽然看起来符合我的预期 - 是我的数据帧的三倍长。有人可以建议如何修复上述代码吗?或者,建议一个更干净的解决方案,它可以(1)使用字典值(域名)过滤数据帧的“链接”列,同时(2)创建字典键(出版物名称)的新“发布”列? (请注意,为简洁起见,此处创建的 df 仅包含一列;实际文件将包含许多列,因此我必须能够指定要过滤的列。)
编辑:我想对RagingRoosevelt的回答进行一些澄清。我想避免使用合并,因为某些域可能不完全匹配。例如,对于 ajc.com
,我还希望能够捕获 myajc.com
,对于 washingtonpost.com
,我希望能够捕获也想获得像 live.washingtonpost.com
这样的子域名。因此,我希望有一种“在字符串中查找子字符串”的解决方案,其中包含 str.contains()
、find()
或 in
> 运算符。
最佳答案
这就是我要做的:
使用DataFrame.apply向仅包含域的数据框添加一个新列。
使用DataFrame.merge (使用
how='inner'
选项)在域字段上合并两个数据框。
如果数据帧只是迭代列或行,那么使用循环对数据帧执行操作有点脏,并且通常有一个 DataFrame 方法可以更干净地执行相同的操作。
如果您愿意,我可以用示例来扩展它。
编辑 这就是它的样子。请注意,我使用相当糟糕的正则表达式来捕获域。
def domain_extract(row):
s = row['Links']
p = r'(?:(?:\w+)?(?::\/\/)(?:www\.)?)?([A-z0-9.]+)\/.*'
m = re.match(p, s)
if m is not None:
return m.group(1)
else:
return None
df['Domain'] = df.apply(domain_extract, axis=1)
dfo = pd.DataFrame({'Name': ['Atlanta Journal-Constitution', 'The Washington Post', 'The New York Times'], 'Domain': ['ajc.com', 'washingtonpost.com', 'nytimes.com']})
df.merge(dfo, on='Domain', how='inner')[['Links', 'Domain', 'Name']]
关于python - 使用字典值过滤数据帧,同时将字典键分配给匹配的行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46007647/