Как перемещаться по строкам данных без использования команды for l oop - PullRequest
0 голосов
/ 27 февраля 2020

У меня есть следующий фрейм данных:

       df = pd.DataFrame({'Day' : ['15', '15', '15', '16', '16', '17', '17', '17', '17'], 
                          'Month' : ['10', '10', '10', '10', '10', '10', '10', '10', '10'], 
                          'Year' : ['2019', '2019', '2019', '2019', '2019', '2019', '2019', '2019', 
                                    '2019'], 
                          'Hour' : ['14', '14', '14', '14', '14', '14', '15', '15', '15'],
                          'Minute' : ['33', '41', '45', '46', '58', '59', '01', '02', '03' ],
                          'Second' : ['16', '17', '19', '19', '20', '0', '0', '0', '0'],
                          'depth' : [40000, 39000, 13000, 40000, 39500, 35000, 34500, 35000, 34600]
                          })

Я использовал эту строку для создания нового столбца даты:

        df['Date'] = pd.to_datetime(df[['Year', 'Month', 'Day', 'Hour', 'Minute', 'Second']])

Существует ограничение на разницу во времени и ограничение на разница между глубинами. Итак, я реализовал следующий код:

      df['Status'] = np.NaN

      for i in range(0, len(df)):    
          for j in range(i+1, len(df)):       

              date_init = pd.to_datetime(df['Date'].iloc[i])
              date_next = pd.to_datetime(df['Date'].iloc[j])


              if(abs(date_init -  date_next) < pd.to_timedelta('0 days 00:10:00')): # 10 minutes          

                 #Calculate the depth variation
                 var_delta_sensor = abs(df['depth'].iloc[i] - df['depth'].iloc[j])


                 if(var_delta_sensor < 1500):

                      #The depth is valid let's accept
                      df['Status'].iloc[i] = 'ACCEPT'
                      df['Status'].iloc[j] = 'ACCEPT'

                  else:
                      #Entering here means that the depth is not valid
                      print("NOT depth")             

              else:
                  #The difference between element i and j is greater than 10 minutes
                  i = j
                  j = i + 1 

Вывод соответствует приведенному ниже кадру данных. Это верно. Это именно тот вывод, который мне нужен, но я использую два FOR, это очень медленно. Мне нужно было работать на 20000 строк данных. Я хотел бы изучить новый, более быстрый способ достижения того же результата. Ткс

       print(df)

      Day   Month   Year    Hour    Minute  Second  depth   Date                Status
      15    10      2019    14        33    16      40000   2019-10-15 14:33:16 ACCEPT
      15    10      2019    14        41    17      39000   2019-10-15 14:41:17 ACCEPT
      15    10      2019    14        45    19      13000   2019-10-15 14:45:19 NaN
      16    10      2019    14        46    19      40000   2019-10-16 14:46:19 NaN
      16    10      2019    14        58    20      39500   2019-10-16 14:58:20 NaN
      17    10      2019    14        59    0       35000   2019-10-17 14:59:00 ACCEPT
      17    10      2019    15        01    0       34500   2019-10-17 15:01:00 ACCEPT
      17    10      2019    15        02    0       35000   2019-10-17 15:02:00 ACCEPT
      17    10      2019    15        03    0       34600   2019-10-17 15:03:00 ACCEPT

1 Ответ

1 голос
/ 28 февраля 2020

Без больших изменений в вашем коде, если вы сравниваете à l'une со следующим, вы можете изменить вложенный l oop:

для i в диапазоне (0, len (df) ):
для j в диапазоне (i + 1, len (df)):

By:

 for i in range(0, len(df)-1):    
      j=i+1

Это позволит вам сэкономить много раз.

Другим решением будет использование функции diff для вычисления var_time и var_sensor. https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.diff.html

Например:

import pandas as pd
import numpy as np
import datetime

df['var_time'] =df['Date'].diff()
df['var_delta_sensor'] =df['depth'].diff().abs()

time_delta=datetime.timedelta(minutes=10) #10 minutes          

df['status']  = np.where((( df['var_time'] < time_delta) & (df['var_delta_sensor'] <1500)), 'Accept', np.NaN) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...