Getting a vector of dictionary values in an array, python

不问归期 提交于 2019-12-24 00:38:26

问题


I am trying to get a vector of specific dictionary values which are in a numpy array. Here is what the array looks like:

import numpy as np
edge_array = np.array(
    [[1001, 7005, {'lanes': 9, 'length': 0.35, 'type': '99', 'modes': 'cw'}],
     [1001, 8259, {'lanes': 10, 'length': 0.46, 'type': '99', 'modes': 'cw'}],
     [1001, 14007, {'lanes': 7, 'length': 0.49, 'type': '99', 'modes': 'cw'}]])

I have a vector for the first two values of each row (i.e. 1001 and 7005, but I need another vector for the values associated with 'lanes'.

Here is my code so far:

row_idx = edge_array[:, 0]
col_idx = edge_array[:, 1]
lane_values = edge_array[:, 2['lanes']]

The error I get is as follows:

lane_values = edge_array[:, 2['lanes']]
TypeError: 'int' object has no attribute '__getitem__'

Please let me know if you need any further clarification, thanks!


回答1:


The subexpression 2['lanes'] does not make sense: you are indexing into the number 2.

Instead, try:

[rec['lanes'] for rec in edge_array[:, 2]]

Or:

import operator
map(operator.itemgetter('lanes'), edge_array[:,2])

The above will give you a regular Python list; if you want a NumPy array you'll have to call np.array() on the list.

But the better solution here is to transform your data into a "structured array" which has named columns and then you can index efficiently by name. If your array has many rows, this will have a big impact on efficiency.




回答2:


This is not a fully working example. Hard to work with that. The types are unclear. I suspect, that you work with numpy somehow, but well, hard to tell.

In all means, the indexing with 2['something'] is incorrect and the error tells you why. It is tried to index with a key in an integer. Look up how indexing is done in python / numpy.

But this is how you could extract your 'lanes':

map(lambda x: x['lanes'], edge_array[:, 2]))
# OR (if you want a vector/np-array)
vec_of_lanes = np.array(map(lambda x: x['lanes'], edge_array[:, 2])))

More in numpy-style:

vec_of_lanes = np.apply_along_axis(lambda x: x[2]['lanes'], 1, edge_array)



回答3:


@Zwinck suggested a structured array. Here's one way of doing that

Define a dtype for the dictionary part. It has fields with different dtypes

dt1 = np.dtype([('lanes',int), ('length',float), ('type','S2'),('modes','S2')])

Embed that dtype in a larger one. I used a sub-array format for the first 2 values:

dt = np.dtype([('f0',int,(2,)), ('f1',dt1)])

Now create the array. I edited your expression to fit dt. The mix of tuples and lists is important. I could have transferred the data from your object array instead (todo?)

edge_array1 = np.array(  
    [([1001, 7005], ( 9,  0.35, '99','cw')),
     ([1001, 8259], ( 10, 0.46, '99','cw')),
     ([1001, 14007], (7,  0.49, '99', 'cw'))], dtype=dt)

Now the 2 int values can be accessed by the 'f0' field name:

In [513]: edge_array1['f0']
Out[513]: 
array([[ 1001,  7005],
       [ 1001,  8259],
       [ 1001, 14007]])

while 'lanes' are accessed by a double application of field name indexing (since they are a field within the field):

In [514]: edge_array1['f1']['lanes']
Out[514]: array([ 9, 10,  7])


来源:https://stackoverflow.com/questions/37226428/getting-a-vector-of-dictionary-values-in-an-array-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!