如何将列表与DataFrame列匹配并生成带编号的新列
解决方案:为DataFrame的URL列匹配源并生成编号列
你的问题出在循环的逻辑上:你现在的代码是检查整个df.source列是否包含某个源,然后直接给整列的sourcenum赋值当前计数器值,最后所有行都会被覆盖成最后一个计数器值(如果初始没赋值的话就会是0),而不是逐行判断每个URL对应的源。
下面给你几个高效可行的实现方法:
方法1:字典 + apply(最直观)
用你已经定义好的源-编号字典,写一个自定义函数逐行检查URL包含哪个源,返回对应的编号:
import pandas as pd # 定义源-编号字典 sources = {'fox':1, 'yahoo':2, 'abcnews':3, 'google':4, 'cnn':5, 'nyt':6, 'nbc':7, 'washingtonpost':8, 'wsj':9, 'huffingtonpost':10} # 自定义匹配函数 def get_source_num(url): for source, num in sources.items(): if source in url: return num return 0 # 没有匹配到的情况返回0,也可以返回pd.NA # 应用到DataFrame df['sourcenum'] = df['source'].apply(get_source_num)
方法2:np.select + str.contains(向量化操作,效率更高)
np.select其实支持任意数量的条件,你只需要把每个源的条件整理成列表,对应的结果也整理成列表即可:
import pandas as pd import numpy as np sources = {'fox':1, 'yahoo':2, 'abcnews':3, 'google':4, 'cnn':5, 'nyt':6, 'nbc':7, 'washingtonpost':8, 'wsj':9, 'huffingtonpost':10} # 生成条件列表和结果列表 conditions = [df['source'].str.contains(source, case=False) # 可选case=False忽略大小写 for source in sources.keys()] choices = list(sources.values()) # 应用np.select,default是没有匹配到的返回值 df['sourcenum'] = np.select(conditions, choices, default=0)
方法3:正则提取 + map(简洁高效)
把所有源拼成正则表达式,提取URL中匹配的源,再用字典映射成编号:
import pandas as pd sources = {'fox':1, 'yahoo':2, 'abcnews':3, 'google':4, 'cnn':5, 'nyt':6, 'nbc':7, 'washingtonpost':8, 'wsj':9, 'huffingtonpost':10} # 生成匹配所有源的正则表达式 pattern = '|'.join(sources.keys()) # 提取匹配的源,然后映射成编号 df['sourcenum'] = df['source'].str.extract(f'({pattern})', expand=False).map(sources).fillna(0).astype(int)
为什么你的原代码不行?
你的循环逻辑是:
count = 1 for x in sources: if x in df.source.values: # 这里检查的是整个列是否存在x,不是逐行判断 df.sourcenum = count # 直接给整列赋值,会覆盖之前的所有值 count += 1
这会导致只有最后一个满足x in df.source.values的源对应的编号被赋值给整列,而如果没有任何源满足的话,sourcenum会保持初始的0值。
内容的提问来源于stack exchange,提问作者ra37
相关产品推荐
相关产品推荐

