Skip to main content
 首页 » 编程设计

python之具有条件的 Pandas 中两个数据帧的复杂 Map 操作

2024年10月17日33lvdongjie

我在 pandas df 中有一张 table 。

id    prod1    prod2    count 
1      10       30        100 
2      10       20        200 
3      20       10        200 
4      30       10        100 
5      30       40        300 

我在 df2 中还有另一个表

product  price   master_product 
  1000       1          10 
  5000       2          10 
  2000       2          20 
  9000       5          20 
  8000       1          20 
  30         3          0 
  4000       4          50 

检查prod1和prod2是否属于master_product中的值,

如果是 我想用我的 master_product 中最便宜的产品替换我的第一个 df 中的 prod1 和 prod2。

如果 prod1 和 prod2 值与 master_product 中的值不匹配, 保持值不变。

我正在寻找决赛 table 。

id    prod1    prod2    count 
1      1000    4000        100 
2      1000    8000        200 
3      8000    1000        200 
4      30       1000        100   #since 30 is not in master_product,leave as it is 
5      30       40        300 

我试图使用 .map 函数来实现这个 但我只能做到这一点。

df['prod1'] = df['prod1'].map(df2.set_index('master_product')['product']) 
df['prod2'] = df['prod2'].map(df2.set_index('master_product')['product']) 

但它会尝试用 df2 的 master_product 中的匹配值替换 prod1 和 prod2 中的每个值。

有什么想法可以实现吗?

请您参考如下方法:

您可以先修改 df1 为 master_product by groupby 的最低 price与 idxmin - 以最小的 price 获取所有指数:

df1 = df1.loc[df1.groupby('master_product')['price'].idxmin()] 
print (df1) 
   product  price  master_product 
5       30      3               0 
0     1000      1              10 
4     8000      1              20 
6     4000      4              50 

为映射创建dict:

d = df1.set_index('master_product')['product'].to_dict() 
print (d) 
{0: 30, 10: 1000, 20: 8000, 50: 4000} 

最后map如果缺少值,请通过 combine_first 添加它:

df.prod1 = df.prod1.map(d).combine_first(df.prod1) 
df.prod2 = df.prod2.map(d).combine_first(df.prod2) 
print (df) 
   id   prod1   prod2  count 
0   1  1000.0    30.0    100 
1   2  1000.0  8000.0    200 
2   3  8000.0  1000.0    200 
3   4    30.0  1000.0    100 
4   5    30.0    40.0    300