【问题标题】:Mapping ndarray of labels to values in a pandas Series将标签数组映射到熊猫系列中的值
【发布时间】:2016-01-20 19:40:19
【问题描述】:

这可能是错误的通用方法,但我正在尝试使用 Pandas 系列作为一些字符串/标签的 numpy 数组的查找表:

import pandas as pd
import numpy as np

data_map = pd.Series([2, 4, 6, 0, 1], index=list('abcde'))
lab1d = np.array(['a', 'd', 'd', 'c'])
lab2d = np.array([['d', 'e'],
                  ['e', 'd'],
                  ['c', 'a'],
                  ['a', 'b']])

val1d = data_map.loc[lab1d]
val2d = data_map.loc[lab2d]

如果我这样做,val1d 会正确解析为:

a    2
d    0
d    0
c    6
dtype: int64

但是val2d = data_map.loc[lab2d] 提出了ValueError

ValueError: Cannot index with multidimensional key

我想我明白了这不起作用的原因,但正确的方法是获取包含索引值的大小 (m x n) 的 numpy.ndarray 并返回(可以转换为的东西)numpy.ndarray size (m x n) 包含对应的值吗?

编辑 我曾考虑将数据存储在字典中并使用numpy.vectorize(如this question 所示),这绝对是我的后备方案,但我想澄清一下我有兴趣知道是否有办法使用一些 pandas 方法。

编辑 2 我应该澄清一下,我实际上是在寻找遵循广播规则的东西,例如:

dmd = data_map.to_dict()
make_map = np.vectorize(dmd.__getitem__)

val1d = make_map(lab1d)
val2d = make_map(lab2d)

val1d 的返回值:

array([2, 0, 0, 6])

对于 val2d 返回:

array([[0, 1],
       [1, 0],
       [6, 2],
       [2, 4]])

【问题讨论】:

  • 注意:如果我的“编辑 2”示例基本上是执行此操作的“正确”方式,那么我认为这个问题可以作为 the linked question 的副本关闭。

标签: python arrays numpy pandas vectorization


【解决方案1】:

这是使用np.searchsorted 的矢量化方法 -

data_map[np.searchsorted(np.array(data_map.index),lab1d)]
data_map[np.searchsorted(np.array(data_map.index),lab2d)]

示例运行 -

>>> data_map = pd.Series([2, 4, 6, 0, 1], index=list('abcde'))
>>> lab1d = np.array(['a', 'd', 'd', 'c'])
>>> lab2d = np.array([['d', 'e'],
...                   ['e', 'd'],
...                   ['c', 'a'],
...                   ['a', 'b']])
>>> data_map[np.searchsorted(np.array(data_map.index),lab1d)]
a    2
d    0
d    0
c    6
dtype: int64
>>> data_map[np.searchsorted(np.array(data_map.index),lab2d)]
array([[0, 1],
       [1, 0],
       [6, 2],
       [2, 4]])

【讨论】:

  • 这看起来不错。与 %timeit 相比,它比基于字典的查找慢 2-3 倍,但这看起来基本上是使用 numpy 数组和 pandas Series 的正确方法。
  • @Paul 嗯,很有趣。我真的希望它快点!也许它会使用更大的数据集和查找!
【解决方案2】:

您可以将数组展平,然后重塑:

data_map[lab2d.ravel()].reshape(lab2d.shape)

【讨论】:

  • 将接受的答案切换到这个答案,因为这实际上与基于 dict 的方法一样快,并且更具可读性和直接性。
猜你喜欢
  • 2019-09-28
  • 1970-01-01
  • 2021-09-03
  • 2019-05-19
  • 2020-09-25
  • 1970-01-01
  • 2019-01-02
  • 2021-03-01
  • 1970-01-01
相关资源
最近更新 更多