Chr*_*ler 5 python arrays numpy type-conversion
我有一些数据用numpy数组存储dtype=object
,我想提取列表的一列并将其转换为numpy数组。看来这是一个简单的问题,但是我发现解决此问题的唯一方法是将整个对象重铸为列表列表,然后将其重铸为numpy数组。还有更Python化的方法吗?
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,)
Run Code Online (Sandbox Code Playgroud)
将数组重铸为dtype=str
会引发一个,ValueError
因为它试图将每个列表转换为一个字符串。
arr.astype(str)
# ValueError: setting an array element with a sequence
Run Code Online (Sandbox Code Playgroud)
可以将整个数组重建为列表列表,然后将其强制转换为numpy数组,但这似乎是一种回旋方式。
arr_2 = np.array(list(arr))
type(arr_2)
# numpy.ndarray
type(arr_2[0])
# numpy.ndarray
arr_2.shape
# (2, 3)
Run Code Online (Sandbox Code Playgroud)
有一个更好的方法吗?
hpa*_*ulj 10
虽然通过列表的方式比通过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
Run Code Online (Sandbox Code Playgroud)
vstack
是在做:
np.concatenate([np.atleast_2d(a) for a in arr[:,1]],axis=0)
Run Code Online (Sandbox Code Playgroud)
一些替代方案:
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
Run Code Online (Sandbox Code Playgroud)
请记住,对象数组只包含指向内存中其他位置的列表的指针。虽然 的 2d 性质arr
使选择第二列变得容易,但arr[:,1]
实际上是一个列表列表。并且对它的大多数操作都是这样对待它的。诸如此类的reshape
事情不要跨越那个object
界限。
一种方法是使用堆叠操作,例如np.vstack
-
np.vstack(arr[:, 1])
Run Code Online (Sandbox Code Playgroud)
样品运行 -
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')
Run Code Online (Sandbox Code Playgroud)
我相信np.vstack
会在内部使用np.concatenate
. 因此,要直接使用它,我们将 -
np.concatenate(arr[:, 1]).reshape(len(arr),-1)
Run Code Online (Sandbox Code Playgroud)