如何从numpy记录数组的一行中选择部分列?

5 投票
2 回答
3869 浏览
提问于 2025-04-18 09:52

我知道像 x[['col1','col2']] 这样的写法可以用来从一个 numpy 记录数组中选择列。我的问题是,如何在记录数组的单行上执行相同的操作。这里是我想做的:

Python 2.7.7 (default, Jun  2 2014, 01:41:14)
[...]
IPython 2.1.0 -- An enhanced Interactive Python.
[...]

In [1]: import numpy as np

In [2]: x = np.ones(3, dtype=[('a',float),('b',float),('c',int)])

In [3]: x[['b','c']][0]
Out[3]: (1.0, 1)

In [4]: row0 = x[0]

In [5]: row0['b']
Out[5]: 1.0

In [6]: row0['c']
Out[6]: 1

In [7]: row0[['b','c']]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-7-287722bfeeaa> in <module>()
----> 1 row0[['b','c']]

IndexError: invalid index

我希望最后的语句能得到结果 (1.0, 1),但我却得到了上面显示的错误。我该如何从 row0 中提取指定的列呢?

我实际应用中有很多列,而我需要哪些列取决于我当前所在的行,所以我不能在行之前就选择列。由于 row0[['b','c']] 这样的操作会执行很多次,我希望能避免在这里使用 Python 循环。

我问题的一部分可能是因为我不知道 row0 的数据类型:

In [8]: row0
Out[8]: (1.0, 1.0, 1)

In [9]: row0.dtype
Out[9]: dtype([('a', '<f8'), ('b', '<f8'), ('c', '<i8')])

row0 有一个 dtype,所以它显然不是一个普通的 Python 元组。但它似乎也不是一个 numpy 数组:

In [10]: type(row0)
Out[10]: numpy.void

2 个回答

1

在文档里找不到关于如何以你想要的方式访问记录数组的任何信息。我试了试,发现这样做似乎有效:

>>> x = np.ones(3, dtype=[('a',float),('b',float),('c',int)])
>>> r = np.array(x[0])
>>> r
array((1.0, 1.0, 1), 
      dtype=[('a', '<f8'), ('b', '<f8'), ('c', '<i4')])
>>> r[['a','c']]
(1.0, 1)
>>> 

r 看起来是对 x 的一种视图:

>>> r['a'] = 3
>>> r
array((3.0, 1.0, 1), 
      dtype=[('a', '<f8'), ('b', '<f8'), ('c', '<i4')])
>>> x
array([(3.0, 1.0, 1), (1.0, 1.0, 1), (1.0, 1.0, 1)], 
      dtype=[('a', '<f8'), ('b', '<f8'), ('c', '<i4')])
3

问题是,当你使用 x[0] 时,你得到的是一个 np.void 对象,它的维度是0。这意味着它只是一个单一的值,没有任何额外的结构。如果你想要一个有结构的数组,可以用 x[0:1],这样你就会得到一个 np.ndarray 对象,它的维度是1,这样就可以选择列了。

r0 = x[0:1]
r0[['b', 'c']]
#array([(1.0, 1)],
#      dtype=[('b', '<f8'), ('c', '<i4')])

你也可以把这个 np.void 转换成 np.ndarray,方法是:

r0 = x[0]
r0 = r0.reshape(-1)

这样也能选择列。

撰写回答