Skip to main content
 首页 » 编程设计

python之使用两个数据框计算最终值 pandas

2025年05月04日22xiaohuochai

目前,我有两个数据框,我正在合并“KEY”。我的第一个数据框包含一个 KEY 和产品的原价。我的第二个数据框收集一个人每次付款的信息。我需要在 df1 中创建一个最终计算列来显示余额。剩余余额是通过从 original_price 中减去 payment_price 计算得出的。唯一需要注意的是,只有某些 price_codes 反射(reflect)了付款(13、14 和 15)。

我不确定最好的方法是使用合并,还是我可以简单地引用另一个 df 而不必合并(后一种方法似乎更理想,因为两个 df 都有 500,000,000 多行),但我找不到关于这个特定场景的很多内容。

df1 = pd.DataFrame({'KEY': ['100000555', '100000009','100000034','100000035', '100000036'],  
              'original_price': [1205.20,1253.25,1852.15,1452.36,1653.21], 
              'area': [12, 13, 12,12,12]}) 
df2 = pd.DataFrame({'KEY': ['100000555', '100000009', '100000009', '100000009', '100000009','100000034','100000034', '100000034'],  
              'payment_price': [134.04, 453.43, 422.32,23.23,10.43,10.47,243.09,23.45], 
              'Price_code': ['13', '13', '14','15','16','13','14','15']}) 

df1:

    KEY         area    original_price 
0   100000555   12      1205.20 
1   100000009   13      1253.25 
2   100000034   12      1852.15 
3   100000035   12      1452.36 
4   100000036   12      1653.21 

df2:

    KEY         payment_price    Price_code 
0   100000555   134.04           13 
1   100000009   453.43           13 
2   100000009   422.32           14 
3   100000009   23.23            15 
4   100000009   10.43            16 
5   100000034   10.47            13 
6   100000034   243.09           14 
7   100000034   23.45            15 

我需要创建一个计算,如果它们与键匹配并且 price_code 值为 13、14 或 15,我需要从 df2 中减去任何 payment_price。

最终结果

    KEY         area    original_price    calculated_price 
0   100000555   12      1205.20           1071.16          # (1205.20 - 134.04) 
1   100000009   13      1253.25           354.27           # (1253.25 - 453.43 - 422.32 - 23.23) 
2   100000034   12      1852.15           1575.14          # (1852.15 - 10.47 - 243.09 - 23.45) 
3   100000035   12      1452.36           1452.36 
4   100000036   12      1653.21           1653.21 

我最初的想法是合并两个 df 并使用 groupby 语句执行计算。但我对此犹豫不决,因为这似乎占用了大量资源,而且我最终的 df 至少是行数的两倍。此外,我遇到了一个心理障碍,无法编写仅包含某些 price_codes 的计算。所以现在我想知道是否有更好的方法。我愿意接受其他方法或帮助此脚本。 老实说,我不完全确定如何为这样的 price_codes 编写条件。下面的代码首先合并 dfs,然后创建一个列 (remaining_price)。但是,对于 KEY 10000009,我只需要包含 price_codes 12、14、15 并排除 16,但目前包含 16。

result = pd.merge(df1, df2,how='left', on='KEY') 
 
codes = [13,14,15] 
result['remaining_price'] = result['original_price'] - result['payment_price'].groupby(result['KEY']).transform('sum') 

最后,我假设如果这是我使用的方法,我将需要删除 KEY 和两个合并列(price_code、payment_price)上的所有重复行。

result = result.drop_duplicates(subset=['KEY'],keep='first') 

请您参考如下方法:

这是一种方法。无需显式合并或删除重复项。这是您可能会看到性能改进的地方。

解决方案

s = df2[df2['Price_code'].isin([13, 14, 15])].groupby('KEY')['payment_price'].sum() 
 
df1['calculated_price'] = df1['original_price'] - df1['KEY'].map(s).fillna(0) 

结果

         KEY  area  original_price  calculated_price 
0  100000555    12         1205.20           1071.16 
1  100000009    13         1253.25            354.27 
2  100000034    12         1852.15           1575.14 
3  100000035    12         1452.36           1452.36 
4  100000036    12         1653.21           1653.21 

解释

  • 按要求按Price_code过滤df2,按KEY聚合payment_price,最后求和。结果是将 KEY 映射到付款总和的系列。
  • 使用 map 将这些总和映射到 df1 中的 KEY,并从 original_price 中减去。