【问题标题】:Updating values for a subset of a subset of a pandas dataframe too slow for large data set更新熊猫数据帧子集的子集的值对于大型数据集来说太慢了
【发布时间】:2021-10-18 19:44:18
【问题描述】:

问题陈述:我正在处理所有医院就诊的交易数据,我需要在每个患者的第一次坏账交易之后删除。

我遇到的问题:我的代码适用于一个小型数据集,但实际数据集大约为 5GB 和 13M 行。代码已经运行了好几天了,仍然没有完成。作为背景,我的代码位于标准工作 PC 上运行的 Jupyter 笔记本中。

样本数据

import pandas as pd

    df = pd.DataFrame({"PatientAccountNumber":[113,113,113,113,225,225,225,225,225,225,225], 
                       "TransactionCode":['50','50','77','60','22','77','25','77','25','77','77'],
                       "Bucket":['Charity','Charity','Bad Debt','3rd Party','Self Pay','Bad Debt',
                                 'Charity','Bad Debt','Charity','Bad Debt','Bad Debt']})
    
    
    print(df)

示例数据框

    PatientAccountNumber TransactionCode     Bucket
0                    113              50    Charity
1                    113              50    Charity
2                    113              77   Bad Debt
3                    113              60  3rd Party
4                    225              22   Self Pay
5                    225              77   Bad Debt
6                    225              25    Charity
7                    225              77   Bad Debt
8                    225              25    Charity
9                    225              77   Bad Debt
10                   225              77   Bad Debt

解决方案

for account in df['PatientAccountNumber'].unique():
    mask = (df['PatientAccountNumber'] == account) & (df['Bucket'] == 'Bad Debt')
    df.drop(df[mask].index[1:],inplace=True)

print(df)

期望结果(每位患者最多应有一笔坏账交易)

   PatientAccountNumber TransactionCode     Bucket
0                   113              50    Charity
1                   113              50    Charity
2                   113              77   Bad Debt
3                   113              60  3rd Party
4                   225              22   Self Pay
5                   225              77   Bad Debt
6                   225              25    Charity
8                   225              25    Charity

替代解决方案

for account in df['PatientAccountNumber'].unique():
    mask = (df['PatientAccountNumber'] == account) & (df['Bucket'] == 'Bad Debt')
    mask = mask & (mask.cumsum() > 1)
    df.loc[mask, 'Bucket'] = 'DELETE'

df = df[df['Bucket'] != 'DELETE]

尝试使用 Dask

我认为也许 Dask 可以帮助我,但我收到以下错误代码:

  1. 在第一个解决方案中使用 Dask -“NotImplementedError: Series getitem in only supported for other series objects with matching partition structure”
  2. 在第二个解决方案中使用 Dask -“TypeError: '_LocIndexer' 对象不支持项目分配”

【问题讨论】:

    标签: python pandas performance bigdata dask


    【解决方案1】:

    创建一个没有循环的布尔掩码:

    mask = df[df['Bucket'].eq('Bad Debt')].duplicated('PatientAccountNumber')
    df.drop(mask[mask].index, inplace=True)
    
    >>> df
       PatientAccountNumber TransactionCode     Bucket
    0                   113              50    Charity
    1                   113              50    Charity
    2                   113              77   Bad Debt
    3                   113              60  3rd Party
    4                   225              22   Self Pay
    5                   225              77   Bad Debt
    6                   225              25    Charity
    8                   225              25    Charity
    

    【讨论】:

      【解决方案2】:

      您可以在 accountNumber 和 Bucket 上使用 df.duplicated 并检查 Bucket 是否为坏账来解决此问题:

      df[~(df.duplicated(['PatientAccountNumber','Bucket']) & df['Bucket'].eq("Bad Debt"))]
      

         PatientAccountNumber TransactionCode     Bucket
      0                   113              50    Charity
      1                   113              50    Charity
      2                   113              77   Bad Debt
      3                   113              60  3rd Party
      4                   225              22   Self Pay
      5                   225              77   Bad Debt
      6                   225              25    Charity
      8                   225              25    Charity
      

      【讨论】:

      • 我以前怎么没想到! +1
      • 太棒了,谢谢!它将处理时间从大约 6 天减少到 9 秒 :)
      猜你喜欢
      • 2017-05-05
      • 2016-03-28
      • 1970-01-01
      • 2017-11-26
      • 2019-10-28
      • 2021-05-29
      • 2019-03-19
      • 1970-01-01
      • 2018-06-12
      相关资源
      最近更新 更多