将一个numpy数组的列表转换成一个numpy数组

11 人关注

我有一些数据是以 dtype=object 的numpy数组形式存储的,我想提取一列列表并将其转换成numpy数组。 这似乎是一个简单的问题,但我发现解决它的唯一方法是把整个东西重铸为一个列表,然后再重铸为一个numpy数组。 是否有更多的pythonic方法?

import numpy as np
arr = np.array([[1, ['a', 'b', 'c']], [2, ['a', 'b', 'c']]], dtype=object)
arr = arr[:, 1]
print(arr)
# [['a', 'b', 'c'] ['a', 'b', 'c']]
type(arr)
# numpy.ndarray
type(arr[0])
# list
arr.shape
# (2,)

将数组重铸为dtype=str会产生一个ValueError,因为它试图将每个列表转换为字符串。

arr.astype(str)
# ValueError: setting an array element with a sequence

可以把整个数组重建为一个列表,然后把它投成一个numpy数组,但这似乎是一个迂回的方法。

arr_2 = np.array(list(arr))
type(arr_2)
# numpy.ndarray
type(arr_2[0])
# numpy.ndarray
arr_2.shape
# (2, 3)

有什么更好的方法吗?

1 个评论
一个对象数组只不过是一个美化的(或贬低的)列表而已。 数组中的元素是指向那些列表对象的指针。 对这样一个数组的大多数操作都涉及到列表迭代。
python
arrays
numpy
type-conversion
Chris Mueller
Chris Mueller
发布于 2016-10-26
2 个回答
hpaulj
hpaulj
发布于 2016-10-26
已采纳
0 人赞同

虽然通过列表的方式比通过 vstack 的方式更快。

In [1617]: timeit np.array(arr[:,1].tolist())
100000 loops, best of 3: 11.5 µs per loop
In [1618]: timeit np.vstack(arr[:,1])
10000 loops, best of 3: 54.1 µs per loop

vstack is doing:

np.concatenate([np.atleast_2d(a) for a in arr[:,1]],axis=0)

一些替代品。

In [1627]: timeit np.array([a for a in arr[:,1]])
100000 loops, best of 3: 18.6 µs per loop
In [1629]: timeit np.stack(arr[:,1],axis=0)
10000 loops, best of 3: 60.2 µs per loop

请记住,对象数组只是包含指向内存中其他地方的列表的指针。 虽然arr的二维性质使得它很容易选择第二列,但arr[:,1]实际上是一个列表的列表。 大多数操作都是这样处理的。 像reshape这样的东西并没有跨越object的边界。

Divakar
Divakar
发布于 2016-10-26
0 人赞同

一种方法是使用叠加操作,如 np.vstack -

np.vstack(arr[:, 1])

样品运行-

In [234]: arr
Out[234]: 
array([[1, ['a', 'b', 'c']],
       [2, ['a', 'b', 'c']]], dtype=object)
In [235]: arr[:,1]
Out[235]: array([['a', 'b', 'c'], ['a', 'b', 'c']], dtype=object)
In [236]: np.vstack(arr[:, 1])
Out[236]: 
array([['a', 'b', 'c'],
       ['a', 'b', 'c']], 
      dtype='|S1')