Python: поиск по списку векторизации - PullRequest
0 голосов
/ 03 ноября 2018

У меня есть данные датчика, такие как:

{"Time":1541203508.45,"Tc":25.4,"Hp":33}
{"Time":1541203508.45,"Tc":25.2,"Hp":32}
{"Time":1541203508.45,"Tc":25.1,"Hp":31}
{"Time":1541203508.45,"Tc":25.2,"Hp":33}

Я делаю много поисков по списку в цикле for следующим образом:

output={}
for i,data in enumerate(sensor_data):
    output[i]={}
    output[i]['H']=['V_Dry','Dry','Normal','Humid','V_Humid','ERR']([sensor_data[i]['Hp'])%20]
    #.... And so on for temp etc

Есть ли способ векторизовать это, если я преобразовал его в тип данных numpy / pandas? Например, если я разделю разделы на временные значения, влажность и т. Д., Есть ли метод python, который применил бы к нему такую ​​«маску»?

Является ли карта моей единственной возможностью ускорить ее?

1 Ответ

0 голосов
/ 03 ноября 2018

Первая попытка

Я предлагаю вам сначала преобразовать ваши данные в пустой массив:

import numpy as np
data = [{"Time":1541203508.45,"Tc":25.4,"Hp":33},
{"Time":1541203508.45,"Tc":25.2,"Hp":32},
{"Time":1541203508.45,"Tc":25.1,"Hp":31},
{"Time":1541203508.45,"Tc":25.2,"Hp":33}]
np_data = np.asarray([list(element.values()) for element in data])

Теперь третий столбец - это влажность в вашем примере. Давайте теперь определим map для этого:

def convert_number_to_hr(value):
    hr_names = ['V_Dry','Dry','Normal','Humid','V_Humid','ERR']
    return hr_names[int(value//20)]

Это использует ваши предопределенные имена с шагом 20%. Теперь давайте применим map:

hr_humidity = map(convert_number_to_hr, np_data[:,2])

Это генератор. Вы можете перебрать его или преобразовать в список через list(hr_humidity).

Это сообщает скорость

%timeit hr_humidity = map(convert_number_to_hr, np_data[:,2])
515 ns ± 2.25 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Если вы подадите заявку list(..), это время возрастет до

%timeit hr_humidity = list(map(convert_number_to_hr, np_data[:,2]))
5.62 µs ± 18.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Теперь вы можете использовать ту же процедуру для всего остального в вашем наборе данных.

Вторая попытка

Я попытался сделать это полностью векторизованным, как вы и просили в своем комментарии. Я придумал:

def same_but_pure_numpy(arr):
    arr = arr.astype(int)//20
    hr_names = np.asarray(['V_Dry','Dry','Normal','Humid','V_Humid','ERR'])
    return hr_names[arr]

Это сообщает скорость

%timeit a = same_but_pure_numpy(np_data[:,2])
11.5 µs ± 151 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

так что версия map кажется быстрее.

Третья попытка

РЕДАКТИРОВАТЬ: Хорошо, у меня была первая попытка с pandas:

import pandas as pd
data = [{"Time":1541203508.45,"Tc":25.4,"Hp":33},
{"Time":1541203508.45,"Tc":25.2,"Hp":32},
{"Time":1541203508.45,"Tc":25.1,"Hp":31},
{"Time":1541203508.45,"Tc":25.2,"Hp":33}]
df = pd.DataFrame(data)
def convert_number_to_hr(value):
    hr_names = ['V_Dry','Dry','Normal','Humid','V_Humid','ERR']
    return hr_names[int(value//20)]

Результат, как и ожидалось, но, похоже, занимает много времени:

%timeit new = df["Hp"].map(convert_number_to_hr)
110 µs ± 569 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...