在为匹配的行分配字典键时用字典值筛选数据帧?

2024-09-28 03:16:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个dataframe,其中有一个列“Links”,其中包含几千篇在线文章的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'])

另外,我还有一个字典,其中包含publication names作为键,域名作为值。在

^{pr2}$

我想过滤dataframe,以便只得到那些在“Links”列中包含字典值中的域的观察值,同时同时将字典键中的发布名称分配给新列“publication”。我设想的是使用下面的代码创建“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是我的dataframe的三倍长。有人能建议如何修复上述代码吗?或者,也可以建议一个更干净的解决方案,它可以(1)使用字典值(域名)过滤数据框的“Links”列,同时(2)创建字典键(Publication names)的新“Publication”列?(请注意,df是在这里创建的,为了简洁起见,只有一列;实际文件将有许多列,因此我必须能够指定要筛选的列。)

编辑:我想澄清一下RagingRoosevelt的回答。我想避免使用合并,因为有些域可能不完全匹配。例如,使用ajc.com我也希望能够捕获myajc.com,而使用washingtonpost.com我也希望得到类似live.washingtonpost.com的子域。因此,我希望使用str.contains()find()in运算符的“在字符串中查找子字符串”解决方案。在


Tags: inhttpscomhttpdataframedf字典www
2条回答

我能够使用嵌套字典理解(或者,使用嵌套列表理解)和一些额外的数据帧操作来清理列和删除空行。在

使用嵌套词典理解(或者更具体地说,嵌套在列表理解中的词典理解):

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'] != '']

类似地,使用嵌套列表理解

^{pr2}$

我要做的是:

  1. 使用DataFrame.apply向仅包含域的数据帧添加新列。

  2. 使用DataFrame.merge(带how='inner'选项)合并域字段上的两个数据帧。

如果循环只是在列或行上迭代,那么使用循环对数据帧执行操作有点脏,而且通常有一个DataFrame方法可以更干净地执行相同的操作。在

如果你愿意,我可以用例子来扩展。在

编辑下面是这样的。请注意,我在域捕获中使用了相当糟糕的regex。在

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']]

相关问题 更多 >

    热门问题