如何高效对比不同DataFrame的两列数据?以市场价和售价对比为例
采购价与市场价对比的高效实现方案
现有数据表结构
- 商品每日市场价表
market_price,存储单个商品每日的公开市场价,字段包括:date(日期)、commodity(商品ID)、price(当日市场价)
示例数据:
| date | commodity | price |
|---|---|---|
| 2008-12-01 | akfuh3 | 850 |
| 2008-12-02 | akfuh3 | 1034 |
| 2008-12-03 | akfuh3 | 1220 |
| 2008-12-05 | akfuh3 | 1000 |
- 采购报表
purches_report,存储每一笔采购的明细数据,字段包括:date(采购日期)、dealer(经销商)、commodity(采购商品ID)、sale_price(实际采购价)
示例数据:
| date | dealer | commodity | sale_price |
|---|---|---|---|
| 2008-12-01 | ABC | akfuh3 | 850 |
| 2008-12-01 | XYZ | akfuh3 | 855 |
| 2008-12-02 | ABC | akfuh3 | 900 |
| 2008-12-03 | ABC | akfuh3 | 1300 |
| 2008-12-03 | XYZ | akfuh3 | 1300 |
| 2008-12-05 | PQR | akfuh3 | 1050 |
原有实现及缺陷
原有通过合并两表对比的代码如下:
full_report = pd.merge(report, mrkt.drop("commodity",1), on="date") sale_price_higher_than_market = full_report.sale_price > full_report.price
存在的问题:同一日期存在多条采购记录时,合并操作会将单条市场价数据重复拷贝对应采购记录的次数,数据量较大时会占用过多内存。
优化方案
方案1:映射法(内存占用最低,推荐优先使用)
不需要做全表合并,直接将市场价转换为键值对映射,在采购表上直接做判断,完全不会产生冗余数据。
如果是多商品场景,以日期+商品ID作为唯一映射键:
# 构造市场价映射字典 price_map = market_price.set_index(['date', 'commodity'])['price'].to_dict() # 直接在采购表上生成判断列 purches_report['is_higher_than_market'] = purches_report.apply( lambda x: x['sale_price'] > price_map[(x['date'], x['commodity'])], axis=1 )
如果是单商品场景,仅需日期作为映射键,可进一步简化:
price_map = market_price.set_index('date')['price'].to_dict() purches_report['is_higher_than_market'] = purches_report['sale_price'] > purches_report['date'].map(price_map)
方案2:索引对齐拼接(适合需要保留市场价字段的场景)
如果后续计算需要保留市场价字段,可以通过设置公共索引的方式拼接列,相比普通merge内存占用更低:
# 给两张表设置共同的组合索引 purches_report = purches_report.set_index(['date', 'commodity']) market_price = market_price.set_index(['date', 'commodity']) # 直接拼接市场价列,无冗余数据拷贝 purches_report['market_price'] = market_price['price'] # 生成判断列 purches_report['is_higher_than_market'] = purches_report['sale_price'] > purches_report['market_price'] # 按需重置索引恢复原有表结构 purches_report = purches_report.reset_index()
内容的提问来源于stack exchange,提问作者anonymous
相关产品推荐
相关产品推荐

