You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于外层DataFrame行过滤内层DataFrame及动态计算实现方案

问题:基于外层DataFrame行过滤内层DataFrame实现门店预算与实际销售额统计

目标

基于外层DataFrame(门店列表)的行及其值,过滤内层DataFrame(销售记录),展示各门店的预算销售额、实际销售额及两者差值。

数据定义

三个初始DataFrame:

  • 门店列表:
import pandas as pd

Shop = pd.DataFrame({
    'Shop_number': ['SH10','SH20', 'SH30','SH40' ,'SH50','SH60','SH70'],
    'Shop': ['Chisinau','Milan', 'Paris','Madrid', 'Lyon','London', 'foo']
})
  • 实际销售记录:
Sales = pd.DataFrame({
    'Shop_number': ['SH20', 'SH30', 'SH50','SH70'],
    'Amount':[200,400,50,1000],
    'Type' : 'Actual'
})
  • 预算销售记录:
Budget = pd.DataFrame({
    'Shop_number': ['SH10','SH20', 'SH30','SH40' ,'SH50','SH60','SH70'],
    'Amount':[100,150,200,300,40,500,150],
    'Type' : 'Budget'
})

合并为基础数据:

base = pd.concat([Sales, Budget])

尝试的错误代码及报错

尝试通过assign动态关联门店编号时触发报错:

(Shop
    .assign(
        Budget = lambda x : 
            base.loc[(base['Shop_number']==x.Shop_number) & (base['Type']=='Budget')].loc[:,'Amount'].sum(),
        Actual = lambda x : 
            base.loc[(base['Shop_number']==x.Shop_number) & (base['Type']=='Actual')].loc[:,'Amount'].sum(),
        var = lambda x : 
            x.Budget-x.Actual
    )
)

报错信息:

ValueError: Can only compare identically-labeled Series objects


解答

1. 修改现有代码实现动态关联

报错原因是x.Shop_number是整个Series,与base['Shop_number']比较时会按索引对齐,两者索引不匹配导致错误。改用apply逐行处理每个门店编号即可解决:

(Shop
    .assign(
        Budget = lambda df: df['Shop_number'].apply(lambda sn: base.loc[(base['Shop_number'] == sn) & (base['Type'] == 'Budget'), 'Amount'].sum()),
        Actual = lambda df: df['Shop_number'].apply(lambda sn: base.loc[(base['Shop_number'] == sn) & (base['Type'] == 'Actual'), 'Amount'].sum()),
        var = lambda df: df['Budget'] - df['Actual']
    )
)

通过df['Shop_number'].apply()逐个提取门店编号sn,再去base中过滤对应记录并求和,避免了Series间的索引对齐问题。

2. 更优的实现方式

推荐使用分组聚合+宽表转换+合并的矢量化操作,效率远高于逐行apply,尤其适合大数据量场景:

# 1. 按门店编号和销售类型分组求和,转换为宽表
agg_base = base.groupby(['Shop_number', 'Type'])['Amount'].sum().unstack(fill_value=0)

# 2. 与门店列表左连接,确保所有门店都被保留
result = Shop.merge(agg_base, on='Shop_number', how='left')

# 3. 计算差值
result['var'] = result['Budget'] - result['Actual']

这种方式利用pandas的矢量化操作替代循环,代码更简洁,执行效率更高,同时逻辑更清晰。


内容的提问来源于stack exchange,提问作者send_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 07:14:54