如何基于另一DataFrame为test2新增'total views'列?
问题:为DataFrame添加匹配求和列
现有两个DataFrame:
test1 = pd.DataFrame({'text':['harrypotter, legendsandlattes', 'legendsandlattesissocool','poems','midnightlibrary','legendsandlattes'], 'views':[200,400,300,600,100]}) test2 = pd.DataFrame({'title':['legendsandlattes', 'harrypotter', 'Prideandprejudice'], 'rating':[8,6, 8]})
需要给test2新增total views列,规则是:
- 只要test2的
title在test1的text单元格里出现,就把该单元格的views累加到对应title的总数里(同一个text单元格里有多个title的话,每个title都加这行的views) - 没出现过的title,
total views填0
期望得到的结果:
| title | rating | total views |------------------|--------|------------- | legendsandlattes | 8 | 700 | harrypotter | 6 | 200 | Prideandprejudice| 8 | 0
之前已经用下面的代码实现了判断title是否存在的tiktok列,现在要改成求和逻辑:
test2['tiktok'] = np.where(test2['title'].str.contains('|'.join(test1['text'])), 1, 0)
解决方案
方法一:简洁向量化实现(适合大多数场景)
直接用apply遍历test2的每个title,筛选test1中包含该title的行并求和views:
import pandas as pd import numpy as np # 原始数据 test1 = pd.DataFrame({'text':['harrypotter, legendsandlattes', 'legendsandlattesissocool','poems','midnightlibrary','legendsandlattes'], 'views':[200,400,300,600,100]}) test2 = pd.DataFrame({'title':['legendsandlattes', 'harrypotter', 'Prideandprejudice'], 'rating':[8,6, 8]}) # 新增total views列 test2['total views'] = test2['title'].apply( lambda x: test1[test1['text'].str.contains(x, na=False)]['views'].sum() ) # 查看结果 print(test2)
方法二:分步拆解实现(逻辑更清晰)
如果觉得上面的代码有点抽象,可以拆成三步,逻辑更直观:
- 遍历test1的每一行,找出所有匹配的title,记录对应的views
- 按title分组求和,得到每个title的总views
- 把求和结果合并到test2,未匹配的填充0
代码如下:
import pandas as pd import numpy as np # 原始数据 test1 = pd.DataFrame({'text':['harrypotter, legendsandlattes', 'legendsandlattesissocool','poems','midnightlibrary','legendsandlattes'], 'views':[200,400,300,600,100]}) test2 = pd.DataFrame({'title':['legendsandlattes', 'harrypotter', 'Prideandprejudice'], 'rating':[8,6, 8]}) # 步骤1:收集所有匹配的title和对应views matches = [] for _, row in test1.iterrows(): current_text = row['text'] current_views = row['views'] # 检查每个title是否在当前text里 for title in test2['title']: if title in current_text: matches.append({'title': title, 'views': current_views}) # 步骤2:分组求和 title_total_views = pd.DataFrame(matches).groupby('title')['views'].sum().reset_index() # 步骤3:合并到test2,填充未匹配的0 test2 = test2.merge(title_total_views, on='title', how='left') test2 = test2.rename(columns={'views': 'total views'}).fillna(0) # 查看结果 print(test2)
两种方法都能得到期望的结果,小数据量下选方法一更简洁,大数据量可以根据情况优化方法二的循环逻辑。
内容的提问来源于stack exchange,提问作者Romcom1398
相关产品推荐
相关产品推荐

