簡體   English   中英

從 Numpy Ndarray 構建字典和列表

[英]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)

這是將dictzipslicing結合使用的一種方法。

前任:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM