Как я могу перебирать данные списка быстрее, используя многопроцессорность? - PullRequest
0 голосов
/ 10 апреля 2020

Я пытаюсь определить количество времени, отработанное списком сотрудников во время их смены на сайте - эти данные предоставляются мне в виде файла CSV. Оттуда я помещаю данные в матрицу и перебираю их, используя некоторое время l oop, применяя необходимые условия (например, вычитая 30 минут на обед). Затем он помещается в новый список, который используется для создания рабочего листа Excel.

Мой сценарий выполняет то, что должен, но занимает очень много времени, когда приходится l oop через много данных (требуется l oop через примерно 26 000 строк). Моя идея состоит в том, чтобы использовать многопроцессорную обработку для параллельного выполнения следующих трех циклов:

  1. Преобразование времени из чч: мм: сс в минуты.
  2. L oop и применение условных выражений .
  3. Округлите значения и преобразуйте их в часы, чтобы это не делалось в больших значениях, пока l oop.

Это хорошая идея? Если это так, как бы я мог выполнять циклы параллельно, когда мне нужны данные из одного l oop для использования в следующем? Моя первая мысль - использовать функцию time для задержки, но потом я обеспокоен тем, что мои циклы могут «догнать» друг друга и выплюнуть, что вызываемый индекс списка не существует.

Любые более опытные мнения были бы удивительны, спасибо!

Мой сценарий:

import pandas as pd

Функция: округлить время до следующих младших десяти минут -> 77 = 70; 32 = 30:

def floor_time (n, десятичные = 0):

multiplier = 10 ** decimals
return int(n * multiplier) / multiplier

Функция: Получить данные из таблицы Excel:

def get_data ():

df = pd.read_csv('/Users/Chadd/Desktop/dd.csv', sep = ',')
list_of_rows = [list(row) for row in df.values]
data = []
i = 0
while i < len(list_of_rows):
    data.append(list_of_rows[i][0].split(';'))
    data[i].pop()
    i += 1
return data

Функция: Преобразование временного индекса в данных в 24-часовую шкалу:

def get_time (time_data):

return int(time_data.split(':')[0])*60 + int(time_data.split(':')[1])

Функция: L oop через данные в CSV применение условий:

def get_time_worked ():

i = 0 # Looping through entry data
j = 1 # Looping through departure data
list_of_times = []

while j < len(get_data()):

    start_time = get_time(get_data()[i][3])
    end_time = get_time(get_data()[j][3])

     # Morning shift - start time < end time
    if start_time < end_time:
        time_worked = end_time - start_time # end time - start time (minutes)
        # Need to deduct 15 minutes if late:
        if start_time > 6*60: # Late
            time_worked = time_worked - 15
        # Need to set the start time to 06:00:00:
        if start_time < 6*60: # Early
            time_worked = end_time - 6*60

    # Afternoon shift - start time > end time
    elif start_time > end_time:
        time_worked = 24*60 - start_time + end_time # 24*60 - start time + end time (minutes)
        # Need to deduct 15 minutes if late:
        if start_time > 18*60: # Late
            time_worked = time_worked - 15
        # Need to set the start time to 18:00:00:
        if start_time > 18*60: # Early
            time_worked = 24*60 - 18*60 + end_time

    # If time worked exceeds 5 hours, deduct 30 minutes for lunch:
    if time_worked >= 5*60:
        time_worked = time_worked - 30

    # Set max time worked to 11.5 hours:
    if time_worked > 11.5*60:
        time_worked = 11.5*60

    list_of_times.append([get_data()[i][1], get_data()[i][2], round(floor_time(time_worked, decimals = -1)/60, 2)])

    i += 2
    j += 2

return list_of_times

Сохранить данные в лист Excel:

def save_data ():

file_heading = '{} to {}'.format(get_data()[0][2], get_data()[len(get_data())-1][2])
file_heading_2 = file_heading.replace('/', '_')

df = pd.DataFrame(get_time_worked())
writer = pd.ExcelWriter('/Users/Chadd/Desktop/{}.xlsx'.format(file_heading_2), engine='xlsxwriter')
df.to_excel(writer, sheet_name='Hours Worked', index=False)
writer.save()

save_data ()

1 Ответ

2 голосов
/ 10 апреля 2020

Вы можете посмотреть на multiprocessing.Pool, который позволяет выполнять функцию несколько раз с разными входными переменными. Из документов

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    with Pool(5) as p:
        print(p.map(f, [1, 2, 3]))

Затем нужно разделить ваши данные на куски (вместо [1, 2, 3] в примере).
Но, мои личные предпочтения , это взять время и узнать что-то, что распространяется по умолчанию. Такие как Spark и pyspark. Это поможет вам в конечном итоге очень.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...