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

基于另一DataFrame公共列对目标DataFrame执行计算的Pandas实现

问题需求

有两个列结构相同但行数不同的DataFrames,已找出两者的公共项(同category_id和size),需要将Nike产品的sell_price更新为同类别、同尺码的Adidas产品unit_price的1.1倍,得到目标结果。


原始数据

percent = 1.10

data1 = {
    'item_id': [1001, 1002, 1003, 1004],
    'brand': ['Adidas', 'Adidas', 'Adidas', 'Adidas'],
    'category_id': [241, 241, 238, 717],
    'size': [8, 7.5, 9, 10],
    'cost_price': [8.02, 4.94, 1.49, 18.44],
    'unit_price': [12.89, 7.98, 2.44, 29.53]
}

data2 = {
    'item_id': [1005, 1006, 1007, 1008],
    'brand': ['Nike', 'Nike', 'Nike', 'Nike'],
    'category_id': [512, 241, 604, 717],
    'size': [7.5, 8, 9, 10],
    'cost_price': [35.90, 11.62, 15.03, 20.53],
    'unit_price': [48.14, 16.29, 21.09, 28.20]
}

adidas = pd.DataFrame(data1)
nike = pd.DataFrame(data2)

已找到的公共项

columns = ['category_id', 'size']
common = adidas[columns].merge(nike[columns])
# common输出:
#    category_id  size
# 0          241   8.0
# 1          717  10.0

df = pd.concat([adidas, nike]).merge(common)
# df输出:
#    item_id   brand  category_id  size  cost_price  unit_price
# 0     1001  Adidas          241   8.0        8.02       12.89
# 1     1006    Nike          241   8.0       11.62       16.29
# 2     1004  Adidas          717  10.0       18.44       29.53
# 3     1008    Nike          717  10.0       20.53       28.20

两种繁琐的尝试

尝试1:字典遍历匹配

cat_match = []
for catid in data2['category_id']:
    try:
        index = data1['category_id'].index(catid)
        cat_match.append(index)
    except ValueError:
        pass

size_match = []
for size in data2['size']:
    try:
        index = data1['size'].index(size)
        size_match.append(index)  # 原代码存在笔误,此处修正
    except ValueError:
        pass

print(cat_match)  # [0, 3]
print(size_match) # [1, 0, 2, 3]

这种方式需要手动后续匹配索引计算,步骤繁琐且易出错。

尝试2:apply函数(报错)

nike['new_sell'] = nike.apply(lambda row: row['unit_price'] * 1.10 if row['category_id'] == adidas['category_id'] and row['size'] == adidas['size'] else None, axis=1)

报错信息:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

原因是lambda中直接将行值与整个Series比较,导致布尔值判断歧义。


简洁解决方案

利用Pandas的merge关联+向量化计算,一步完成需求:

# 从adidas中提取关联键和定价,计算加价后的值
adidas_pricing = adidas[['category_id', 'size', 'unit_price']].copy()
adidas_pricing['sell_price'] = adidas_pricing['unit_price'] * percent

# 关联nike数据与adidas定价,仅保留有匹配项的Nike产品
nike_updated = nike.merge(adidas_pricing, on=['category_id', 'size'], how='inner')

# 整理列顺序并格式化价格小数位数
nike_updated = nike_updated[['item_id', 'brand', 'category_id', 'size', 'cost_price', 'unit_price', 'sell_price']]
nike_updated['sell_price'] = nike_updated['sell_price'].round(2)

print(nike_updated)

输出结果:

item_id brand  category_id  size  cost_price  unit_price  sell_price
0     1006  Nike          241   8.0       11.62       16.29       14.18
1     1008  Nike          717  10.0       20.53       28.20       32.48

说明

  1. 先从adidas数据中提取关联键(category_id、size)和定价字段,计算出加价后的sell_price;
  2. 使用merge将nike数据与计算后的adidas定价按关联键匹配,how='inner'确保只保留有对应Adidas产品的Nike条目;
  3. 最后整理列顺序并格式化价格小数位数,直接得到目标结果。

这种方法完全利用Pandas的向量化操作,避免了循环和歧义判断,简洁高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 21:40:04