[英]Build Dictionary and List from Numpy Ndarray
我想使用 2D ndarray 為數百萬個數據創建一個字典。
尋找一種pythonic和高性能的方式來實現這一目標
我的數組:
格式:[id、origin_lat、origin_lon、dest_lat、dest_lon、距離]
my_array = np.array([[245, 32.45,63.89,72.1,63.57,123.45],
[246, 61.73,42.71,75.54,-81.69,16.32]])
預期輸出:
my_dict = {
245: {
'origin_lat_lon': {
'lat': 32.45,
'lon': 63.89
},
'dest_lat_lon': {
'lat': 72.1,
'lon': 63.57
},
'distance': 123.45
},
246: {
'origin_lat_lon': {
'lat': 61.73,
'lon': 42.71
},
'dest_lat_lon': {
'lat': 75.54,
'lon': -81.69
},
'distance': 16.32
}
}
my_list = [{'lat': 32.45, 'lon': 63.89},
{'lat': 72.1, 'lon': 63.57},
{'lat': 61.73, 'lon': 42.71},
{'lat': 75.54, 'lon': -81.69}]
我的代碼:
my_dict = dict()
my_list = list()
for arr in my_array:
origin_lat_lon = {'lat': arr[1],
'lon': arr[2]}
dest_lat_lon = {'lat': arr[3],
'lon': arr[4]}
value = {'origin_lat_lon':origin_lat_lon,'dest_lat_lon':dest_lat_lon,'distance':arr[5]}
my_dict[int(arr[0])]=value
my_list.append(origin_lat_lon)
my_list.append(dest_lat_lon)
這是將dict
與zip
和slicing
結合使用的一種方法。
前任:
import numpy as np
my_array = np.array([[245, 32.45,63.89,72.1,63.57,123.45],[246, 61.73,42.71,75.54,-81.69,16.32]])
keys = ['origin_lat', 'origin_lon', 'dest_lat','dest_lon', 'distance']
keys_2 = ['lat', 'lon']
my_dict = {}
my_list = []
for arr in my_array:
key, vals = arr[0], arr[1:]
my_dict[int(key)] = dict(zip(keys, vals))
my_list.extend([[dict(zip(keys_2, vals[0:2]))],[dict(zip(keys_2, vals[2:4]))]])
print(my_dict)
print(my_list)
輸出:
{245: {'dest_lat': 72.1,
'dest_lon': 63.57,
'distance': 123.45,
'origin_lat': 32.45,
'origin_lon': 63.89},
246: {'dest_lat': 75.54,
'dest_lon': -81.69,
'distance': 16.32,
'origin_lat': 61.73,
'origin_lon': 42.71}}
[[{'lat': 32.45, 'lon': 63.89}],
[{'lat': 72.1, 'lon': 63.57}],
[{'lat': 61.73, 'lon': 42.71}],
[{'lat': 75.54, 'lon': -81.69}]]
您的代碼包裝在一個函數中,時間:
In [220]: timeit foo(my_array)
7.14 µs ± 17.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
將數組轉換為列表將時間減半。 tolist()
是一種(相對)快速的將數組轉換為嵌套列表的方法。 迭代列表比迭代數組更快:
In [221]: timeit foo(my_array.tolist())
2.68 µs ± 14.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Rakesh 的版本有點慢(我還沒有確定原因):
In [222]: timeit rakesh(my_array)
18.5 µs ± 63.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [223]: timeit rakesh(my_array.tolist())
9.49 µs ± 26.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Chris 的 pandas 版本要慢一些。 pandas
確實有一個很好的字典接口,但顯然它並不快。 它可能是純 Python,並且因為通用而降低了速度。
In [224]: timeit foo_pd(my_array)
3.35 ms ± 5.69 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Python 字典對於它們所做的事情是有效的,但它們仍然需要一個鍵一個鍵地訪問。 numpy
沒有自己的編譯代碼來處理字典。
===
您的數組可以轉換為結構化數組。 列被替換為按名稱訪問的字段。 所以它更像字典,雖然對於創建json
輸出可能沒有更好的。 (而且它不是速度工具)
In [225]: dt = np.dtype([('id',int),('origin_lat',float),('origin_lon',float),('
...: dest_lat',float),('dest_lon',float),('distance',float)])
In [226]: import numpy.lib.recfunctions as rf
In [228]: sarr =rf.unstructured_to_structured(my_array, dt)
In [229]: sarr
Out[229]:
array([(245, 32.45, 63.89, 72.1 , 63.57, 123.45),
(246, 61.73, 42.71, 75.54, -81.69, 16.32)],
dtype=[('id', '<i8'), ('origin_lat', '<f8'), ('origin_lon', '<f8'), ('dest_lat', '<f8'), ('dest_lon', '<f8'), ('distance', '<f8')])
In [230]: sarr['dest_lon']
Out[230]: array([ 63.57, -81.69])
In [236]: timeit sarr =rf.unstructured_to_structured(my_array, dt)
46.3 µs ± 1.7 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.