【问题标题】:Using two dataframes to calculate final value pandas使用两个数据框计算最终值 pandas
【发布时间】:2018-08-10 02:06:57
【问题描述】:

目前,我有两个要在“KEY”上合并的数据框。我的第一个数据框包含一个 KEY 和产品的原始价格。我的第二个数据框收集一个人每次付款的信息。我需要在 df1 中创建一个显示余额的最终计算列。余额的计算方法是从 original_price 中减去 payment_price。唯一需要注意的是,只有某些 price_codes 反映了付款(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

我最初的想法是合并两个 dfs 并使用 groupby 语句执行计算。但我对此犹豫不决,这似乎资源繁重,我的最终 df 将至少是行数的两倍。此外,我遇到了一个心理障碍,无法编写仅包含某些价格代码的计算。所以现在我想知道是否有更好的方法。我愿意接受其他方法或对此脚本的帮助。 老实说,我不完全确定如何为 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')

【问题讨论】:

    标签: python pandas dataframe merge pandas-groupby


    【解决方案1】:

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

    解决方案

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

    【讨论】:

    • 谢谢。当我为 13、14、15 添加引号时,这对我有用:isin(['13', '14', '15'])
    【解决方案2】:
    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()
    

    【讨论】:

      猜你喜欢
      • 2020-06-01
      • 2016-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多