基于参考表过滤创建新列的Pandas优化方法求助
问题解决:基于参考表计算新数据列
问题描述
需要根据df中的Total Bags Packed列,匹配bagwt表中对应袋子的重量(Wt)并相乘得到总重量,但当前循环实现后,Total Lbs列的每行都是Series对象,无法正常转换为浮点型列。
问题原因
循环中每次返回的是筛选后的bagwt的Wt列(Series类型),而非单个数值,导致lbs列表中存储的是一个个Series,赋值给DataFrame列后就会出现每行都是Series的情况。
最优实现方式
Pandas推荐使用矢量化操作替代循环,既高效又能避免类型问题。这里可以通过提取匹配键、映射重量值来实现:
步骤1:提取匹配用的Bag Type
从Bag Product Code中提取与bagwt匹配的Bag Type(取.之后的部分):
df['Bag Type'] = df['Bag Product Code'].str[4:] # 截取第4位及之后的字符,即.后面的内容
步骤2:构建重量映射字典
将bagwt转换为以Bag Type为键、Wt为值的字典,方便快速匹配:
bagwt_map = bagwt.set_index('Bag Type')['Wt'].to_dict()
步骤3:计算总重量列
直接用矢量化乘法计算,无需循环:
df['Total Lbs'] = df['Total Bags Packed'] * df['Bag Type'].map(bagwt_map)
完整代码示例
import pandas as pd df = pd.DataFrame({ 'Total Bags Packed': [2220, 3320, 2400, 18], 'Bag Product Code': ['20G.428', '76Q.435', '76Q.435', '76Q.S14'] }) bagwt = pd.DataFrame({ 'Bag Type': ['197','207','209','211','367','417','428','430','431','435','467','750','431L','S04','S12','S13','S14','S16','S25','S26','S28','S75','445'], 'Wt': [50,2000,1800,1500,55,1200,55,55,55,50,1100,1650,55,55,2645,1300,1400,1650,2250,2600,700,750,50] }) # 提取Bag Type df['Bag Type'] = df['Bag Product Code'].str[4:] # 构建重量映射 bagwt_map = bagwt.set_index('Bag Type')['Wt'].to_dict() # 计算总重量 df['Total Lbs'] = df['Total Bags Packed'] * df['Bag Type'].map(bagwt_map) print(df['Total Lbs'])
输出结果
0 122100.0 1 166000.0 2 120000.0 3 25200.0 Name: Total Lbs, dtype: float64
替代方案:使用Merge合并表
如果需要保留bagwt中的其他列,也可以用合并表的方式实现:
# 提取Bag Type df['Bag Type'] = df['Bag Product Code'].str[4:] # 合并表,匹配重量 df = df.merge(bagwt, on='Bag Type', how='left') # 计算总重量 df['Total Lbs'] = df['Total Bags Packed'] * df['Wt']
内容的提问来源于stack exchange,提问作者Chris Paz
相关产品推荐
相关产品推荐

