优化pandas df.loc中的eval以计算来自多个查询、多个条件的n行

2024-06-16 15:55:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个有一些汽车故障的熊猫数据帧示例

VinNumber   Date        Time        Repair Type  Garage Type    Indicator Noise      Dashboard   Condition
JMFE88888   2019-05-15  11:09:00    CONVENTIONAL    3   MECH    BATT      BUZZ       DIMMING     POOR IDLING    
JMFE99999   2019-05-15  15:43:00    CONVENTIONAL    3   MECH    CHK ENG   SPUTTERING N/A         LOSS OF POWER

我已将特定汽车故障的标准组合到如下词典中:

ALTERNATOR = {'Indicator': ('ALT','BATT'),
              'Noise': ('RATTLE','BUZZ'),
              'Dashboard': ('FLICKERING','DIMMING'),
              'Condition': ('RUNS BAD','WILL NOT START')}

其中,每个列名都包含一个元组,每个列中都包含满足字典条件/条件所需的值

因此,为了将一行计算为交流发电机故障,必须在指示器列中显示“ALT”或“BATT”,在噪音列中显示“Crattle”或“BUZZ”,等等

然后,我制作了一系列其他字典,比如交流发电机,但针对不同的缺陷,我将字典的字符串名称放在一个列表中

DEFECTS = ['ALTERNATOR', 'TRANSMISSION', 'ENGINE', 'FUEL_PUMP', 'AC_HEAT', 'RADIO', ... ...]

所以如果我要打字

eval('ALTERNATOR')

我会把真正的字典和它的内容打印出来

最后,我创建了一个字典,在那里我可以保存每辆车的特定缺陷数量(内部或机械)

car_defects = {car: {'INT': {'AC_HEAT': 0, 'RADIO': 0,
                                   'UPHOLSTERY': 0, 'AIRBAGS': 0},
                             'MECH': {'ALTERNATOR': 0, 'TRANSMISSION': 0,
                                   'ENGINE': 0, 'FUEL_PUMP': 0}} for car in df['VinNumber'].unique()}

在该词典中,每辆车都有自己的特定缺陷计数,我使用以下代码得到:

for c in df['VinNumber'].unique(): # for every unique car in the dataframe
  for p in ['INT', 'MECH']: # Interior or Mechanical
    for defect in DEFECTS:
      car_defects[c][p][defect] = df.loc[(df['VinNumber'] == c) &
                                         (df['Type'].str[1] == p) & (df['Indicator'].isin(eval(defect)['Indicator'])) &
                                         (df['Noise'].isin(eval(defect)['Noise'])) &
                                         (df['Dashboard'].isin(eval(defect)['Dashboard'])) &
                                         (df['Condition'].isin(eval(defect)['Condition']))]['VinNumber'].count()

因此,对于MECH和INT中的每个缺陷,以及数据帧中的每个唯一的VIN编号,代码会查看有多少行可以作为该缺陷的实例进行计数,并将这些行的计数分配给存储在该缺陷、该位置(p)和该特定VIN编号(c)的值

代码可以工作,但是在一个11k行的数据帧上,在VinNumber列中有478个唯一值,速度非常慢。我怀疑嵌套循环是导致速度减慢的唯一原因,但我尝试了下面的示例,没有eval或df.loc部分,并且dict值赋值非常快,即使在更大的字典上也是如此。这让我相信eval或df.loc都是导致速度减慢的原因,有没有办法优化这段代码并使其运行得更快

food = {n: {1: {'rice': 0, 'beans': 0, 'noodles': 0, 'eggs': 0, 'flour': 0, 'cheese': 0, 'poultry': 0, 'beef': 0, 'fruits': 0, 'veggies': 0},
            2: {'rice': 0, 'beans': 0, 'noodles': 0, 'eggs': 0, 'flour': 0, 'cheese': 0, 'poultry': 0, 'beef': 0, 'fruits': 0, 'veggies': 0}} for n in range(0, 3500)}


for n in range(0, 3500):
   for i in [1, 2]:
      for foo in ['rice', 'beans', 'noodles', 'eggs', 'flour', 'cheese', 'poultry', 'beef','fruits', 'veggies']:
...      food[n][i][foo] = 9001

Tags: 代码indffor字典evalconditioncar