2016-05-14 3 views
2

Я пытаюсь получить вектор определенных значений словаря, которые находятся в массиве numpy. Вот что массив выглядит следующим образом:.Получение вектора значений словаря в массиве, python

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'}]]) 

У меня есть вектор для первых двух значений каждой строки (т.е. 1001 и 7005, но мне нужен еще один вектор для значений, связанных с 'lanes'

Здесь мой код до сих пор:

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

Я получаю ошибку выглядит следующим образом:

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

Пожалуйста, дайте мне знать, если вам нужно дальнейшее разъяснение, спасибо!

+0

Обратите внимание, что 'dtype' этого массива является' object'. 'edge_array [:, 2]' функционально совпадает с списком словарей. Таким образом, вы должны использовать операции с списками (карта, понимание) для работы с отдельными словарями. – hpaulj

ответ

5

Подвыражение 2['lanes'] не имеет смысла: вы индексирование в число 2.

Вместо этого попробуйте:

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

Или:

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

выше даст вам регулярный Python list; если вам нужен массив NumPy, вам нужно будет позвонить np.array() в список.

Но лучшим решением здесь является преобразование ваших данных в «структурированный массив», который имеет названные столбцы, а затем вы можете эффективно индексировать имя. Если в вашем массиве много строк, это будет иметь большое влияние на эффективность.

+0

Я получаю следующую ошибку при попытке: 'lane_values ​​= edge_array [:, 2] ['lanes'] IndexError: только целые числа, срезы (': '), эллипсис (' ... '), numpy.newaxis ('None') и целые или логические массивы являются действительными индексами. –

+1

@AndrewEarl: Теперь, когда вы обновили свой вопрос с точными входными данными, я обновил свой ответ с помощью точного решения. –

+0

Работает как шарм! Благодарю. Я рассмотрю создание структурированного массива, поскольку у меня много, много и много строк. –

2

Это не совсем рабочий пример. Трудно работать с этим. Типы неясны. Я подозреваю, что вы как-то работаете с numpy, но хорошо, трудно сказать.

Иными словами, индексирование с 2 ['something'] неверно, и ошибка сообщает вам, почему. Он пытается индексировать ключом в целое число. Посмотрите, как индексирование выполняется в python/numpy.

Но это, как вы могли извлечь ваши 'полосы':

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

Больше в Numpy стиле:

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

Привет, спасибо, попробуем это сейчас. Как бы вы предложили создать полностью рабочий пример? Это потому, что 'edge_array' не работает в вашем коде? –

+0

Проблема заключалась в том, что вы только что показали нам печатный результат, поэтому это недействительный синтаксис python, поскольку запятые опущены. Также неясно, указали ли вы списки индексов или массивы numpy. – sascha

+0

Хорошо, я работаю с массивом numpy и редактировал это. Извините за то, что я любитель, но после того, как я реализовал: 'map (lambda x: x ['lanes'], edge_array [:, 2]))' как мне создать вектор из значений 'lanes'? –

0

@Zwinck предложил структурированный массив. Вот один из способов сделать это:

Определите dtype для словарной части. Он имеет поля с разными типами

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

Вставить этот dtype в большой. Я использовал формат вспомогательных массивов для первых двух значений:

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

Теперь создайте массив. Я отредактировал ваше выражение, чтобы оно соответствовало dt. Важное значение имеет сочетание кортежей и списков. Я мог бы перенести данные из вашего массива объектов (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) 

Теперь 2 ИНТ значения могут быть доступны «f0» имя поля:

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

в то время как «полосы» доступны двойным применением имя поля индексации (так как они являются поле в поле):

In [514]: edge_array1['f1']['lanes'] 
Out[514]: array([ 9, 10, 7]) 
Смежные вопросы