将列表与数据框列进行比较并使用数字创建新列

Posted

技术标签:

【中文标题】将列表与数据框列进行比较并使用数字创建新列【英文标题】:Comparing a list to a dataframe column and create new column with numbers 【发布时间】:2018-10-23 11:08:14 【问题描述】:

我有一个数据框,其中一列包含网址。我想将它与字符串值列表进行比较,并在它们匹配的任何地方添加一个数字到一个新列。

该列看起来像这样:

source
www.fox5.com/some_article
www.nyt.com/some_article
www.fox40news.com/some_article
www.cnn.com/another_article
...

我想将其与此列表进行比较:

sources = ['fox', 'yahoo', 'abcnews', 'google', 'cnn', 'nyt', 'nbc', 
'washingtonpost', 'wsj', 'huffingtonpost']

如果源值包含在源列中,则将列表位置的相应编号添加到新列。因此,生成的新列将如下所示:

    sources                       sourcenum
www.fox5.com/some_article         1
www.nyt.com/some_article          6
www.fox40news.com/some_article    1
www.cnn.com/another_article       5
...                               ... 

我尝试过使用带有计数的 for 循环:

count = 1
for x in sources:
    if x in df.source.values:
        df.sourcenum = count
    count += 1

但输出全是 0

我也尝试使用 numpys where 但它不接受 10 个参数。

如果这样会更好的话,可以将列表更改为字典

sources = 'fox':1, 'yahoo':2, 'abcnews':3, 'google':4, 'cnn':5, 'nyt':6, 
       'nbc':7, 'washingtonpost':8, 'wsj':9, 'huffingtonpost':10

任何帮助将不胜感激,谢谢。

【问题讨论】:

【参考方案1】:

一种方法是使用带有enumerate 的生成器表达式。在下面的实现中,我们循环遍历枚举的sources 列表。 next 提取部分匹配的第一个实例。如果不存在部分匹配,则返回0

sources = ['fox', 'yahoo', 'abcnews', 'google', 'cnn', 'nyt', 'nbc', 
           'washingtonpost', 'wsj', 'huffingtonpost']

def sourcer(x):
    return next((i for i, j in enumerate(sources, 1) if j in x), 0)

df['sourcenum'] = df['source'].apply(sourcer)

print(df)

                           source  sourcenum
0       www.fox5.com/some_article          1
1        www.nyt.com/some_article          6
2  www.fox40news.com/some_article          1
3     www.cnn.com/another_article          5

【讨论】:

【参考方案2】:

看起来正则表达式可以帮助解决问题。 Python有're'模块,虽然我不是Python专家。

但想法是用您的源列表组成一个“模式”,并将该模式​​与字符串匹配。我相信你可以得到你需要的匹配数。

【讨论】:

【参考方案3】:

你也可以使用tldextract包来获取url的域名。

然后,应用 get_close_matches 函数 difflib 包获取最接近的字符串。

最后使用.index从源列表中获取对应的索引号:

import tldextract
from difflib import get_close_matches
df['sourcenum'] = df['source'].apply(lambda row:sources.index(
                                get_close_matches(
                                tldextract.extract(row).domain, sources, cutoff=.5)[0])+1)
print(df)

结果:

                           source  sourcenum
0       www.fox5.com/some_article          1
1        www.nyt.com/some_article          6
2  www.fox40news.com/some_article          1
3     www.cnn.com/another_article          5

注意: 在上面的代码中,对于函数 get_close_matches,设置了 cutoff=.5 的值,否则未找到与 fox40news 的紧密匹配。

【讨论】:

以上是关于将列表与数据框列进行比较并使用数字创建新列的主要内容,如果未能解决你的问题,请参考以下文章

根据每个句子的第一个单词将 pandas 数据框列中的字符串列表分解为新列

如何访问 pandas 数据框列中的字典元素并对其进行迭代以创建填充有各自值的新列?

迭代循环并将列表添加到新行或新列中的数据框

在火花数据框中使用 for 循环添加新列

Python - 使用 +/- 振荡值迭代数据框并根据条件创建新列

将列表列表中的值映射到 Pandas 数据框列