【发布时间】:2016-01-17 00:44:04
【问题描述】:
我想让一个数组作用于字典并返回相应的值。而不是循环通过它会很好地以pythonic方式做到这一点,即类似
results[:] = dict[np_vec[:]]
这不起作用,我希望也许有一种我不知道的方法?
在这种情况下,np_vec 具有与字典中的键相对应的整数,而值是元组,我希望在 results 中有一个它们的列表。
【问题讨论】:
标签: python numpy dictionary
我想让一个数组作用于字典并返回相应的值。而不是循环通过它会很好地以pythonic方式做到这一点,即类似
results[:] = dict[np_vec[:]]
这不起作用,我希望也许有一种我不知道的方法?
在这种情况下,np_vec 具有与字典中的键相对应的整数,而值是元组,我希望在 results 中有一个它们的列表。
【问题讨论】:
标签: python numpy dictionary
最直接的 Pythonic(即使用良好的 Python 语法)方法是
results = [dict[value] for value in np_vec]
如果dict 可能没有value,这需要改进。
Can I use a list comprehension on a list of dictionaries if a key is missing?
但也许您希望通过矢量化numpy 表达式传递一些东西。关键是字典一次只能访问一个键
另一种可能性是使用dict.keys() 获取键列表,并使用numpy 方法将np_vec 与此列表匹配。不保证这会更快。
in1d文档
> in1d(a, b) is roughly equivalent to np.array([item in b for item in a]).
我正在考虑类似的事情(但细节可能会关闭)
keys = dict.keys()
values = dict.values()
mask = np.in1d(dict.keys(), np_vec)
result = values[mask]
使用数组的工作代码:
带有数字键、元组值的字典:
In [302]: adict={k:v for k,v in zip([0,1,2,3,4,5],[(0,1),(1,2),(2,3),(3,4),(4,5)])}
In [303]: adict
Out[303]: {0: (0, 1), 1: (1, 2), 2: (2, 3), 3: (3, 4), 4: (4, 5)}
我们要获取的键数组
In [304]: npvec=np.arange(4)
字典列表:
In [305]: keys=list(adict.keys())
In [308]: values=list(adict.values())
In [309]: values
Out[309]: [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
mask - 我们想要提取的键
In [310]: mask=np.in1d(keys,npvec)
In [311]: mask
Out[311]: array([ True, True, True, True, False], dtype=bool)
要一步应用mask,我们必须使用一个数组; keys[mask] 不起作用:
In [313]: np.array(keys)[mask]
Out[313]: array([0, 1, 2, 3])
如果values 是简单数字,但它们是元组,则同样适用。
In [314]: np.array(values)[mask]
Out[314]:
array([[0, 1],
[1, 2],
[2, 3],
[3, 4]])
我们可以将二维数组重新转换为元组列表。
但要保留元组(或其他通用 Python 对象值),我们必须做一些更复杂的事情,例如
In [315]: varray=np.empty(len(values),dtype=object)
In [317]: for i in range(5):varray[i]=values[i]
In [318]: varray
Out[318]: array([(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)], dtype=object)
现在我们可以应用mask 并获得正确的值集。
In [319]: varray[mask]
Out[319]: array([(0, 1), (1, 2), (2, 3), (3, 4)], dtype=object)
将其与简单的列表理解解决方案进行对比:
In [321]: [adict[v] for v in npvec]
Out[321]: [(0, 1), (1, 2), (2, 3), (3, 4)]
有时尝试更 Pythonic,错误 numpy-onic,只是不值得额外的工作。
【讨论】: