使用两个数据帧计算最终值pandas

时间:2018-03-01 21:53:37

标签: python pandas dataframe merge

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

我不确定最佳方法是否利用合并,或者我是否可以简单地引用另一个df而不必合并(后一种方法似乎更理想,因为两个dfs都有500,000,000+行),但我可以&# 39;在这个具体情景中找到很多内容。

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

我最初的倾向是合并两个dfs并使用groupby语句执行计算。但我对此的犹豫是,这似乎资源很重,我的最终df至少是行数的两倍。另外,我遇​​到了一个mental块来编写计算,只包括某些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')

2 个答案:

答案 0 :(得分:3)

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

<强>解决方案

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中减去。

答案 1 :(得分:1)

from dask import delayed

# Use this function for parallel computing using Dask
@delayed
def calc_price(df1, df2):
    """ Calculate original_price - payment_price """

    df3 = (df2[df2['Price_code'] != '16'].groupby('KEY')['payment_price'].sum()).reset_index()
    df1 = df1.merge(df3, how='left', on='KEY').fillna(0)
    df1['calculated_price'] = df1['original_price'].sub( df1['payment_price'])

    return df1

df1 = calc_price(df1, df2).compute()