numpy:如何沿多个轴挤出基础阵列?

时间:2012-01-06 00:41:57

标签: python

假设我有一个像这样的“种子”数组:

>>> import numpy as np
>>> seed = np.array([[2*i, 2*i + 1] for i in range(4)])
>>> seed.shape
(4, 2)

我希望沿着另外两个轴“挤出”这个数组,最后得到一个新的数组,我们称它为extrusion,形状为(5,4,3,2),并且每个有效的索引对( i k ),extrusion[i, :, k, :]处的子阵列(又名“slab”)将是原始种子数组的副本。

  

做这类事情的最佳“最佳做法”是什么?

在下面的附录中,我提出了一些我可以想到的方法,这些方法都利用numpy广播来获得理想的结果,但我希望找到一个对于那些不熟悉的人来说更容易理解的替代方案。与numpy广播。例如。采用“种子”和所需最终形状的构造函数或工厂方法,并在幕后执行所需的挤出。

谢谢!

附录:产生所需挤出的一种方法是将适当形状的零点和适当重新形成的种子阵列加在一起:

>>> shape = 5, 4, 3, 2
>>> zeros = np.zeros(shape, dtype=seed.dtype)
>>> extrusion = seed.reshape((1, 4, 1, 2)) + zeros

(在赋予seed.reshape的形状元组中,获得长度1的轴是挤出将发生的轴。剩余轴的长度必须与所需最终形状的相应轴的长度相匹配。 )

这种方法确实产生了预期的结果;例如,挤出的[1, :, 2, :]平板是种子数组的副本。

>>> extrusion[1, :, 2, :]
array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7]])
>>> seed
array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7]])

创建一个具有正确形状的接收数组稍微不那么苛刻,只需将种子数组分配给它(在适当地重新整形后):

>>> extrusion = np.empty(shape, dtype=seed.dtype)
>>> extrusion[...] = seed.reshape((1, 4, 1, 2))
>>> extrusion[3, :, 2, :]
array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7]])

修改:感谢wim对np.zerosnp.empty来电的建议简化。

1 个答案:

答案 0 :(得分:2)

您可以使用extrusion = np.broadcast_to(seed.reshape(1, 4, 1, 2), (5, 4, 3, 2)) 将阵列广播为所需的形状:

extrusion[...]

这与您extrusion = np.broadcast_to(seed.reshape(1, 4, 1, 2), (5, 4, 3, 2)).copy() 的作业相同的原因相同,但通过广播到给定的形状,您可以在一个表达式中完成。

这将生成原始数组的视图,其中多个结果单元格是原始数组的同一单元格的视图,因此除非您知道完全如何工作,否则不应该改变结果。如果您需要一个可以安全变异的“常规”结果,您可以复制广播结果:

Select tbl.*
From tbl 
Join (
Select loginId,
  TIMESTAMPDIFF(MINUTE, min(logtime),max(logtime))
  As timediff
From tbl
Group by loginId ) tab
  On tbl.loginId = tab.loginId
  Where tab.timediff < 3
  Order by 1, 2