【问题标题】:Numpy: Convert values in a 1-D array based upon dictionaryNumpy:根据字典转换一维数组中的值
【发布时间】:2015-11-15 23:49:31
【问题描述】:

我有以下数组和字典。

>>> 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 都不起作用,因为它们要求输入数组是二维的。

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

【问题讨论】:

  • “非常大”有点含糊。一百万?十亿?远远超过十亿?另外,mapping 大概有多少个键?
  • 你浏览过 numpy 或 scipy 文档看是否有解决方案吗?
  • @WarrenWeckesser:只是一个足够大的数据集,几乎无法放入我的 RAM。 (我正在为退化的情况做准备,我需要为十亿行的数据集做准备。)
  • @wwii:是的。否则,我不会知道np.apply_along_axisnp.apply_over_axis 的功能。

标签: python arrays numpy dictionary


【解决方案1】:

这里有几个想法。

首先,定义一些示例数据:

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

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

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的key数量的情况下,很难说哪种方法更有效。

这是您可能不想使用的方法,因为由表达式 data.reshape(-1, 1) == keys 形成的二维中间数组将具有形状 (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])

【讨论】:

  • 我最喜欢你的第二个答案(在 mapping.items() 上调用 for 循环)。谢谢。
【解决方案2】:

简单地调用map怎么样?

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

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

【讨论】:

  • 正确,这将是一个轻快的方式。但正如您所承认的,此解决方案仅适用于数据集较小且我正在处理大型数据集的情况。
  • 熊猫has a mapfunction。也许你可以试试。
猜你喜欢
  • 2018-02-26
  • 2014-11-14
  • 2019-12-05
  • 2021-01-17
  • 1970-01-01
  • 2018-05-28
  • 2019-05-29
  • 2021-04-04
  • 2011-12-07
相关资源
最近更新 更多