【问题标题】: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}

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

【问题讨论】:

    标签: python string list pandas series


    【解决方案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 的紧密匹配。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-08-14
          • 2021-09-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多