如何在Pandas DataFrame中逐行列比对并按需更新值?
解决方法
首先得明确:你需要先从原始数据里把fortuneId对应的文本内容、vocabId对应的文本内容单独提取出来——因为 pivot 后的表只存了 ratings 值,没有原始文本,没法直接做比对。
步骤1:提取文本映射
先读取原始数据,不要直接 pivot,先构建两个字典来存 ID 和对应文本的映射(假设你的原始 CSV 里,fortune 的文本列叫fortune_text,vocab 的文本列叫vocab_text,如果列名不一样,自行替换):
import pandas as pd # 读取原始数据 raw_df = pd.read_csv('combine.txt') # 构建 fortuneId -> 对应文本的映射(去重避免重复条目) fortune_text_map = raw_df.drop_duplicates('fortuenId').set_index('fortuenId')['fortune_text'].to_dict() # 构建 vocabId -> 对应文本的映射 vocab_text_map = raw_df.drop_duplicates('vocabId').set_index('vocabId')['vocab_text'].to_dict()
步骤2:批量更新ratings值
用矢量化操作生成布尔掩码矩阵,标记需要更新的位置,比逐行逐列循环高效得多:
# 执行你原来的 pivot 操作 df = raw_df.pivot(index='fortuenId', columns='vocabId', values='ratings').fillna(0) # 生成掩码:判断每个 fortune 文本是否包含在对应 vocab 文本中 update_mask = pd.DataFrame( [[fortune_text_map[fortune_id] in vocab_text_map[vocab_id] for vocab_id in df.columns] for fortune_id in df.index], index=df.index, columns=df.columns ) # 只更新原来值为 0 的位置,把符合条件的设为1 df.loc[update_mask & (df == 0)] = 1
为什么iteritems()不好用?
df.iteritems()是按列遍历的,每次返回列名和该列的 Series,没法同时拿到当前行的fortuneId对应的文本内容,自然没法完成文本比对和值更新,所以不适合这个场景。
内容的提问来源于stack exchange,提问作者john
相关产品推荐
相关产品推荐

