Python:矢量化列表查找

时间:2018-11-03 00:13:07

标签: python vectorization

我有这样的传感器数据:

{"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 :(得分:0)

首次尝试

我建议您首先将数据转换为numpy数组:

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)