Numpy:根据字典转换一维数组中的值

时间:2015-08-21 22:53:06

标签: python arrays numpy dictionary

我有以下数组和字典。

>>> data = ['a', 'b', 'a', 'a']
>>> mapping = {'a': 9, 'b': 0}

我想根据此输入字典应用将np.array(['a', 'b', 'a', 'a']转换为np.array([9, 0, 9, 9])的函数。但是我希望这个操作能够被矢量化。如果不使用for loop,我该如何实现这种转换?

请注意,np.apply_along_axisnp.apply_over_axis都不起作用,因为它们要求输入数组为2-D。

编辑:请注意,我正在使用的实际数据集非常大,这里只是一个简单的例子。

2 个答案:

答案 0 :(得分:3)

以下是一些想法。

首先,定义一些样本数据:

In [36]: data = np.array(['a', 'b', 'a', 'a', 'c', 'b'])

In [37]: mapping = {'a': 9, 'b': 0, 'c': 5}

您可以使用numpy.unique获取data中的唯一元素,以及(更重要的是)将这些唯一值映射回输入数组的数组:

In [38]: keys, inv = np.unique(data, return_inverse=True)

此时,keys[inv]会重新创建data。但我们想要创建映射数组,因此我们将在mapping中创建的数组,其顺序与np.unique返回的键相同:

In [39]: vals = np.array([mapping[key] for key in keys])

现在我们可以使用vals索引inv以获得所需的结果:

In [40]: result = vals[inv]

In [41]: result
Out[41]: array([9, 0, 9, 9, 5, 0])

另一种非常简单的方法是简单地循环遍历mapping中的键,并将值的矢量化赋值转换为新数组:

In [42]: result = np.empty(data.size, dtype=int)

In [43]: for key, val in mapping.items():
   ....:     result[data == key] = val
   ....:     

In [44]: result
Out[44]: array([9, 0, 9, 9, 5, 0])

如果不了解data的实际尺寸和mapping中的键数,则很难说哪种方法更有效。

这是您可能不想使用的方法,因为由表达式data.reshape(-1, 1) == keys形成的2-d中间数组将具有形状(len(data), len(mapping))

In [63]: keys = np.array(mapping.keys())

In [64]: vals = np.array(mapping.values())

In [65]: result = vals[(data.reshape(-1, 1) == keys).nonzero()[1]]

In [66]: result
Out[66]: array([9, 0, 9, 9, 5, 0])

答案 1 :(得分:1)

如何简单地拨打map

>>> data = ['a', 'b', 'a', 'a']
>>> mapping = {'a': 9, 'b': 0}
>>> map(lambda x: mapping[x], data)
[9, 0, 9, 9]

这不会使用numpy,如果你的数组很大,也不会非常快,但它很简单,在你遇到性能问题之前可能不会担心。