我有一个带有列的数据框'链接'包含几千个在线文章的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'})
我希望过滤数据框,只获得那些“链接”的观察结果。 column包含字典值中的域,而同时将字典键中的发布名称分配给新列' Publication。'我设想的是使用以下代码来创建出版物'列然后从该列中删除None
以在事后过滤数据帧。
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
运算符的解决方案。
答案 0 :(得分:1)
这就是我要做的事情:
使用DataFrame.merge向仅包含域的数据框添加新列。
使用can't use bind variables(使用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']]
答案 1 :(得分:1)
我能够使用嵌套字典理解(以及使用嵌套列表解析)和一些额外的数据框操作来清理列并删除空行。
使用嵌套字典理解(或者更具体地说,嵌套在列表理解中的字典理解):
df['Publication'] = [{k: k for k,v in urls_dict.items() if v in row} for row in df['Links']]
# Format the 'Publication' column to get rid of duplicate 'key' values
df['Publication'] = df['Publication'].astype(str).str.strip('{}').str.split(':',expand=True)[0]
# Remove blank rows from 'Publication' column
df = df[df['Publication'] != '']
同样,使用嵌套列表理解:
# First converting dict to a list of lists
urls_list_of_lists = list(map(list,urls_dict.items()))
# Nested list comprehension using 'in' operator
df['Publication'] = [[item[0] for item in urls_list_of_lists if item[1] in row] for row in df['Links']]
# Format the 'Publication' column to get rid of duplicate brackets
df['Publication'] = df['Publication'].astype(str).str.strip('[]')
# Remove blank rows from 'Publication' column
df = df[df['Publication'] != '']