重塑任意集合 numpy 数组
reshaping an arbitrary collection numpy arrays
我有一个相对较小的 k 长度 N numpy 数组,其中 k是 10 阶的,N 非常大,10^7 阶。我正在尝试创建一个单一的二维 N x k 数组,以特定方式捆绑此数据。
为明确起见,这是我正在尝试做的具体示例。
x = np.array([0,0,0,0])
y = np.array([1,1,1,1])
z = np.array([2,2,2,2])
最后我要的数组是:
p = np.array([[0,1,2], [0,1,2], [0,1,2], [0,1,2]])
速度是一个关键问题,因此 for 循环慢得令人无法接受。我一直无法弄清楚如何使用 np.reshape 或 np.concatenate 来执行此操作,但我知道必须有一些简单的单行 numpy 语法。
你可以使用 np.concatenate
In [117]: np.concatenate(([x], [y], [z]), axis=0).T
Out[117]:
array([[0, 1, 2],
[0, 1, 2],
[0, 1, 2],
[0, 1, 2]])
此外,您可以迭代追加数组然后转置。
注意:这执行了 3 个循环。
In [113]: arr = np.empty((0,4), int)
In [114]: for el in [x, y, z]:
.....: arr = np.append(arr, [el], axis=0)
.....:
In [115]: arr
Out[115]:
array([[0, 0, 0, 0],
[1, 1, 1, 1],
[2, 2, 2, 2]])
In [116]: arr.T
Out[116]:
array([[0, 1, 2],
[0, 1, 2],
[0, 1, 2],
[0, 1, 2]])
您可以使用 column_stack
:
>>> np.column_stack([x, y, z])
array([[0, 1, 2],
[0, 1, 2],
[0, 1, 2],
[0, 1, 2]])
Internally 这使得三个数组成为 2D(如果可能,不制作副本),转置它们,然后连接它们。 concatenate 函数是一个内部 C 函数,因此它在速度方面可能是高效的。
您可以尝试以下几种方法:
使用vstack
并转置:
p = numpy.vstack((x, y, z)).T
使用concatenate
and reshape
p = numpy.concatenate((x, y, z)).reshape((3, len(x))).T
分配新数组并使用put
p = numpy.empty((len(x), 3))
for i, a in enumerate((x, y, z)):
p[:,i] = a
连同在 iPython 中计算的计时结果,对于 len(x) == len(y) == len(z) == 1e7
:
In [57]: %timeit p = numpy.vstack((x, y, z)).T
10 loops, best of 3: 117 ms per loop
In [58]: %timeit p = numpy.concatenate((x, y, z)).reshape((3, len(x))).T
10 loops, best of 3: 120 ms per loop
In [60]: %timeit p = numpy.column_stack((x, y, z))
10 loops, best of 3: 159 ms per loop
In [66]: %%timeit
....: p = numpy.empty((len(x), 3), order='C')
....: for i, a in enumerate((x, y, z)):
....: p[:,i] = a
....:
10 loops, best of 3: 147 ms per loop
In [67]: %%timeit
....: p = numpy.empty((len(x), 3), order='F')
....: for i, a in enumerate((x, y, z)):
....: p[:,i] = a
....:
10 loops, best of 3: 119 ms per loop
我还包含了 中的方法,并在最后一个中尝试了行优先排序和列优先排序。在时间方面似乎大致有两组方法,120ms 类方法和 150ms 类方法,可能值得注意的是,行优先顺序 ('C'
) 是后一组,而列-主要订单 ('F'
) 是前一组中的一个。
我怀疑这些值不够可靠,无法区分这些方法。我鼓励您自己进行测试,看看哪个最快。
好的,感谢大家的热心解答。正如我所怀疑的那样,numpy 中有一行代码正是为了这个目的。 Transpose、vstack 和 column_stack 都是我所做工作的巨大速度改进。
有四种建议的解决方案,全部return正确的数组:
连接 + 转置 (David Z)
vstack(大卫 Z)
预分配 + 切片赋值 (David Z)
column_stack (ajcr)
下面的结论是:在所有情况下,concatenate + transpose 是最快的算法。
我对解决方案如何与 k 和 N 进行了一些简单的探索,在 k ~ N 范围,以及 k << N 范围。不过,值得注意的是,即使对于非常大的 N,运行 时间也小于 1 秒,因此只有 MCMC 类型的应用程序才应该真正大惊小怪。的事情。
这是我的测试摘要运行:
首先,我可以定量地确认 David Z 的速度测试 运行。此外,在他探索的机制中,我发现他发现的差异是稳健的,而不是简单的波动.见下文。
在 k << N 范围内,我注意到 vstack 和 连接+转置。在这种情况下,无论 k 和 N.[=12 的值如何,它们 return 的时间都在 1-5% 以内=]
在 k << N 范围内,我注意到 column_stack 和预分配和切片赋值。在这种情况下,无论 k 和 N 的值如何,它们 return 的时间都在 1-5% 之内。
在 k << N 范围内,vstack 比 [=65= 快 50-500% ]column_stack。这个分数速度差仅随着 N 缓慢增加,但随着 k 迅速增加。 N越大,随着k.
的分数增长速度越快
在 k ~ N 机制中(与我的问题无关,但可能与其他问题相关),concatenate + transpose 是最快的, 预分配和切片赋值 落后 10-50%。
在k ~ N范围内,column_stack和vstack 速度大致相同,比 concatenate + transpose.
慢 500-1000%
所以,正如我上面所说,结果是 concatenate + transpose 是所有机制中最快的:
p = np.concatenate((x, y, z)).reshape((3, len(x))).T
然而,在与原始问题相关的机制中,vstack 方法具有相同的性能,并且语法规则更少:
p = numpy.vstack((x, y, z)).T
我有一个相对较小的 k 长度 N numpy 数组,其中 k是 10 阶的,N 非常大,10^7 阶。我正在尝试创建一个单一的二维 N x k 数组,以特定方式捆绑此数据。
为明确起见,这是我正在尝试做的具体示例。
x = np.array([0,0,0,0])
y = np.array([1,1,1,1])
z = np.array([2,2,2,2])
最后我要的数组是:
p = np.array([[0,1,2], [0,1,2], [0,1,2], [0,1,2]])
速度是一个关键问题,因此 for 循环慢得令人无法接受。我一直无法弄清楚如何使用 np.reshape 或 np.concatenate 来执行此操作,但我知道必须有一些简单的单行 numpy 语法。
你可以使用 np.concatenate
In [117]: np.concatenate(([x], [y], [z]), axis=0).T
Out[117]:
array([[0, 1, 2],
[0, 1, 2],
[0, 1, 2],
[0, 1, 2]])
此外,您可以迭代追加数组然后转置。
注意:这执行了 3 个循环。
In [113]: arr = np.empty((0,4), int)
In [114]: for el in [x, y, z]:
.....: arr = np.append(arr, [el], axis=0)
.....:
In [115]: arr
Out[115]:
array([[0, 0, 0, 0],
[1, 1, 1, 1],
[2, 2, 2, 2]])
In [116]: arr.T
Out[116]:
array([[0, 1, 2],
[0, 1, 2],
[0, 1, 2],
[0, 1, 2]])
您可以使用 column_stack
:
>>> np.column_stack([x, y, z])
array([[0, 1, 2],
[0, 1, 2],
[0, 1, 2],
[0, 1, 2]])
Internally 这使得三个数组成为 2D(如果可能,不制作副本),转置它们,然后连接它们。 concatenate 函数是一个内部 C 函数,因此它在速度方面可能是高效的。
您可以尝试以下几种方法:
使用
vstack
并转置:p = numpy.vstack((x, y, z)).T
使用
concatenate
andreshape
p = numpy.concatenate((x, y, z)).reshape((3, len(x))).T
分配新数组并使用
put
p = numpy.empty((len(x), 3)) for i, a in enumerate((x, y, z)): p[:,i] = a
连同在 iPython 中计算的计时结果,对于 len(x) == len(y) == len(z) == 1e7
:
In [57]: %timeit p = numpy.vstack((x, y, z)).T
10 loops, best of 3: 117 ms per loop
In [58]: %timeit p = numpy.concatenate((x, y, z)).reshape((3, len(x))).T
10 loops, best of 3: 120 ms per loop
In [60]: %timeit p = numpy.column_stack((x, y, z))
10 loops, best of 3: 159 ms per loop
In [66]: %%timeit
....: p = numpy.empty((len(x), 3), order='C')
....: for i, a in enumerate((x, y, z)):
....: p[:,i] = a
....:
10 loops, best of 3: 147 ms per loop
In [67]: %%timeit
....: p = numpy.empty((len(x), 3), order='F')
....: for i, a in enumerate((x, y, z)):
....: p[:,i] = a
....:
10 loops, best of 3: 119 ms per loop
我还包含了 'C'
) 是后一组,而列-主要订单 ('F'
) 是前一组中的一个。
我怀疑这些值不够可靠,无法区分这些方法。我鼓励您自己进行测试,看看哪个最快。
好的,感谢大家的热心解答。正如我所怀疑的那样,numpy 中有一行代码正是为了这个目的。 Transpose、vstack 和 column_stack 都是我所做工作的巨大速度改进。
有四种建议的解决方案,全部return正确的数组:
连接 + 转置 (David Z)
vstack(大卫 Z)
预分配 + 切片赋值 (David Z)
column_stack (ajcr)
下面的结论是:在所有情况下,concatenate + transpose 是最快的算法。
我对解决方案如何与 k 和 N 进行了一些简单的探索,在 k ~ N 范围,以及 k << N 范围。不过,值得注意的是,即使对于非常大的 N,运行 时间也小于 1 秒,因此只有 MCMC 类型的应用程序才应该真正大惊小怪。的事情。
这是我的测试摘要运行:
首先,我可以定量地确认 David Z 的速度测试 运行。此外,在他探索的机制中,我发现他发现的差异是稳健的,而不是简单的波动.见下文。
在 k << N 范围内,我注意到 vstack 和 连接+转置。在这种情况下,无论 k 和 N.[=12 的值如何,它们 return 的时间都在 1-5% 以内=]
在 k << N 范围内,我注意到 column_stack 和预分配和切片赋值。在这种情况下,无论 k 和 N 的值如何,它们 return 的时间都在 1-5% 之内。
在 k << N 范围内,vstack 比 [=65= 快 50-500% ]column_stack。这个分数速度差仅随着 N 缓慢增加,但随着 k 迅速增加。 N越大,随着k.
的分数增长速度越快
在 k ~ N 机制中(与我的问题无关,但可能与其他问题相关),concatenate + transpose 是最快的, 预分配和切片赋值 落后 10-50%。
在k ~ N范围内,column_stack和vstack 速度大致相同,比 concatenate + transpose.
慢 500-1000%
所以,正如我上面所说,结果是 concatenate + transpose 是所有机制中最快的:
p = np.concatenate((x, y, z)).reshape((3, len(x))).T
然而,在与原始问题相关的机制中,vstack 方法具有相同的性能,并且语法规则更少:
p = numpy.vstack((x, y, z)).T