我有以下np.ndarray:
>>> arr
array([[1, 2],
[3, 4]])
我想将其拆分为X和y,其中每个数组分别是坐标和值。到目前为止,我设法使用np.ndenumerate解决了这个问题:
>>> X, y = zip(*np.ndenumerate(arr))
>>> X
((0, 0), (0, 1), (1, 0), (1, 1))
>>> y
(1, 2, 3, 4)
我想知道是否有一种更惯用和更快的方法来实现它,因为我实际上处理的数组具有数百万个值。
我需要X和y数组将它们稍后传递给sklearn classifier。上面的格式对我来说似乎是最自然的格式,但是也许有更好的方法可以将它们传递给fit
函数。
答案 0 :(得分:1)
将arr
重塑为y
很容易,您可以通过y = arr.flatten()
来实现。我建议将生成X
视为单独的任务。
让我们假设您的数据集的形状为NxM
。在我们的基准测试中,我们将N
设置为500,将M
设置为1000。
N = 500
M = 1000
arr = np.random.randn(N, M)
然后通过使用np.mgrid
并转换索引,您可以得到如下结果:
np.mgrid[:N, :M].transpose(1, 2, 0).reshape(-1, 2)
基准:
%timeit np.mgrid[:N, :M].transpose(1, 2, 0).reshape(-1, 2)
# 3.11 ms ± 35.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit zip(*np.ndenumerate(arr))
# 235 ms ± 1.57 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
根据您的情况,您可以打开包装并通过以下方式获得N
和M
:
N, M = arr.shape
然后:
X = np.mgrid[:N, :M].transpose(1, 2, 0).reshape(-1, 2)
答案 1 :(得分:0)
将numpy.where
与numpy.ravel()
一起使用:
import numpy as np
def ndenumerate(np_array):
return list(zip(*np.where(np_array+1))), np_array.ravel()
arr = np.random.randint(0, 100, (1000,1000))
X_new, y_new = ndenumerate(arr)
X,y = zip(*np.ndenumerate(arr))
输出(验证):
all(i1 == i2 for i1, i2 in zip(X, X_new))
# True
all(y == y_new)
# True
基准测试(快3倍):
%timeit ndenumerate(arr)
# 234 ms ± 20.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit zip(*np.ndenumerate(arr))
# 877 ms ± 91.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)