使用两个数据框计算最终值熊猫

Mar*_*bak 2 python merge dataframe pandas pandas-groupby

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

我不确定最好的方法是否使用合并,或者我是否可以简单地引用另一个 df 而不必合并(后一种方法似乎更理想,因为两个 dfs 都有 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']})
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

我需要创建一个计算,如果它们与键匹配并且 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
Run Code Online (Sandbox Code Playgroud)

我最初的倾向是合并两个 dfs 并使用 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')
Run Code Online (Sandbox Code Playgroud)

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

result = result.drop_duplicates(subset=['KEY'],keep='first')
Run Code Online (Sandbox Code Playgroud)

jpp*_*jpp 5

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

解决方案

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)
Run Code Online (Sandbox Code Playgroud)

结果

         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
Run Code Online (Sandbox Code Playgroud)

解释

  • df2根据需要按 Price_code过滤,按 KEY 汇总 payment_price,最后汇总。结果是将 KEY 映射到付款总和的系列。
  • 用于map将这些总和映射到 KEY indf1并从 original_price中减去。