Python 优化这段代码有困难,想知道为什么它运行得这么慢-我怎么能优化这段代码?

Python 优化这段代码有困难,想知道为什么它运行得这么慢-我怎么能优化这段代码?,python,pandas,dataframe,Python,Pandas,Dataframe,我的一行数据有18列,每列都有一个复杂的代码 并发症类由一个“名称”组成,该名称是并发症名称,如“心衰”,它还有一个存储为“代码”的字符串数组,该字符串的值为“500”,需要在每个患者的18列中进行匹配(每行最终结果),并查找代码,如“5001”或“5002”。如果找到代码,则需要将数据集中相应的复杂度列更新为1 这就是我编写的解决方案。你认为这可以更优化吗?目前,仅在25000名患者身上运行大约需要16分钟,这还不够好 数据: 类别: class HCUPCodes: def __in

我的一行数据有18列,每列都有一个复杂的代码

并发症类由一个“名称”组成,该名称是并发症名称,如“心衰”,它还有一个存储为“代码”的字符串数组,该字符串的值为“500”,需要在每个患者的18列中进行匹配(每行最终结果),并查找代码,如“5001”或“5002”。如果找到代码,则需要将数据集中相应的复杂度列更新为1

这就是我编写的解决方案。你认为这可以更优化吗?目前,仅在25000名患者身上运行大约需要16分钟,这还不够好

数据:

类别:

class HCUPCodes:
    def __init__(self,name,codes):
        self.name = name
        self.codes = codes
类的初始化:

complications_POA = []
complications_POA.append(HCUPCodes('HeartFailure',['80', 'R*1']))
代码:

输出:

DX1      DX2     DX3   DX4 HeartFailure
10R46   R*1005   8017  2   1
10R46   R*10335  5019  2   1
100R91  R*1005   8017  1   1
10R91   R*243    8870  1   0
10M95   R*4918   8305  3   0
10M95   R*9017   8305  3   0
10M95   R*9470   8221  3   0

要实现最低速度,您可以在找到代码后添加
break

 def defineComplicationsFeatures(patient, comp_list):
    for i in range(len(comp_list)):
        for x in comp_list[i].codes:
            if((any(patient.str.startswith(x,na=False)))):
                patient[comp_list[i].name]=1 #change 0 to 1 in the 
                break
    return patient

有两件事会减慢代码的速度:

  • 使用两个for循环
  • 使用
    。使用自己定义的函数应用
  • 您可以使用
    pandas
    numpys
    的矢量化方法优化解决方案:

  • 解决方案:(在这种情况下,我没有使用您的类)

    注意
    您可以将
    col\u to\u update
    &
    strings\u to\u search
    转换为函数的参数,这使函数更简洁,为了简单起见,我现在选择不转换。

    您能用普通语言解释一下吗(首选伪代码)为什么要在预期输出中更新前三行?对于
    startswith()
    ,我找不到任何关于
    na=False
    意味着什么的描述,但您不需要它周围的
    any()
    。但是,我看不到任何明显低效的东西-
    cProfile
    profile
    输出将帮助您了解瓶颈在哪里,我认为。@Erfan:对于数据集中的每一行:如果在第行中找到任何代码,那么:在疾病列中标记1现在这是一个and语句,即必须找到所有代码才能将心衰功能更新为1。如何修改此代码以用作OR操作?不确定您的意思,您想更新比
    HeartFailure
    更多的列吗?
    DX1      DX2     DX3   DX4 HeartFailure
    10R46   R*1005   8017  2   1
    10R46   R*10335  5019  2   1
    100R91  R*1005   8017  1   1
    10R91   R*243    8870  1   0
    10M95   R*4918   8305  3   0
    10M95   R*9017   8305  3   0
    10M95   R*9470   8221  3   0
    
     def defineComplicationsFeatures(patient, comp_list):
        for i in range(len(comp_list)):
            for x in comp_list[i].codes:
                if((any(patient.str.startswith(x,na=False)))):
                    patient[comp_list[i].name]=1 #change 0 to 1 in the 
                    break
        return patient
    
    # Print the DataFrame we start with provided by OP
    print(df)
          DX1      DX2   DX3 DX4  HeartFailure
    0   10R46   R*1005  8017   2             0
    1   10R46  R*10335  5019   2             0
    2  100R91   R*1005  8017   1             0
    3   10R91    R*243  8870   1             0
    4   10M95   R*4918  8305   3             0
    5   10M95   R*9017  8305   3             0
    6   10M95   R*9470  8221   3             0
    
    # Create new optimized function
    def defineComplicationsFeatures(df):
    
        col_to_update = 'HeartFailure'
    
        strings_to_search = ['80', 'R*1']
    
        for string in strings_to_search:
            mask = np.column_stack([df[col].str.startswith(string, na=False) for col in df.iloc[:, :-1]]).any(axis=1)
            df[col_to_update] = np.where(mask, 1, 0)
    
        return df
    
    df_new = defineComplicationsFeatures(df)
    print(df_new)
    
          DX1      DX2   DX3 DX4  HeartFailure
    0   10R46   R*1005  8017   2             1
    1   10R46  R*10335  5019   2             1
    2  100R91   R*1005  8017   1             1
    3   10R91    R*243  8870   1             0
    4   10M95   R*4918  8305   3             0
    5   10M95   R*9017  8305   3             0
    6   10M95   R*9470  8221   3             0