英文:
Numpy tile for complex transformation
问题
Here is the translated code portion:
假设有一个数组
arr = np.array([[1,2,3], [4,5,6]])
我的目标是在`axis = 0`上重复`N = 2`次元素,所以期望的输出是
array([[[1., 4.],
[1., 4.]],
[[2., 5.],
[2., 5.]],
[[3., 6.],
[3., 6.]]])
我尝试过`np.ones((2,2))*arr.T[:,:,None]`,但输出不同
array([[[1., 1.],
[4., 4.]],
[[2., 2.],
[5., 5.]],
[[3., 3.],
[6., 6.]]])
有没有简单的方法来解决这个问题?我猜这涉及到转置,但我不确定如何实现。
**编辑:** 我找到了答案。它是:
np.transpose(np.ones((2,2))*arr.T[:,:,None], axes = tuple([0, 2, 1]))
英文:
Suppose there's an array
arr = np.array([[1,2,3], [4,5,6]])
My goal is to repeat N = 2
times the elements that are on axis = 0
, so the desired output is
array([[[1., 4.],
[1., 4.]],
[[2., 5.],
[2., 5.]],
[[3., 6.],
[3., 6.]]])
I've tried np.ones((2,2))*arr.T[:,:,None]
, but the output differs
array([[[1., 1.],
[4., 4.]],
[[2., 2.],
[5., 5.]],
[[3., 3.],
[6., 6.]]])
Is there an easy way to fix that? In guess it's the matter of transposition, but I'm not sure how to achieve that.
EDIT: I've found the answer. It is:
np.transpose(np.ones((2,2))*arr.T[:,:,None], axes = tuple([0, 2, 1]))
答案1
得分: 2
一种方法
```python
(s0, s1) = arr.strides
np.lib.stride_tricks.as_strided(arr, shape=(3, 2, 2), strides=(s1, 0, s0))
请注意,这基本上是免费的:它什么都不做,并返回相同的 arr
。只是改变了步幅,使迭代沿着新数组的轴0走向 arr
的轴1;只是对轴1重复;以及沿着 arr
的轴0走向新数组的轴2。
对于所有2D arr
大小和所有重复的泛化
def myrepeat(arr, n):
(sh0, sh1) = arr.shape
(st0, st1) = arr.strides
return np.lib.stride_tricks.as_strided(arr, shape=(sh1, n, sh0), strides=(st1, 0, st0))
# 示例
arr = np.arange(20).reshape(4, 5)
myrepeat(arr, 3)
返回
array([[[ 0, 5, 10, 15],
[ 0, 5, 10, 15],
[ 0, 5, 10, 15]],
[[ 1, 6, 11, 16],
[ 1, 6, 11, 16],
[ 1, 6, 11, 16]],
[[ 2, 7, 12, 17],
[ 2, 7, 12, 17],
[ 2, 7, 12, 17]],
[[ 3, 8, 13, 18],
[ 3, 8, 13, 18],
[ 3, 8, 13, 18]],
[[ 4, 9, 14, 19],
[ 4, 9, 14, 19],
[ 4, 9, 14, 19]]])
<details>
<summary>英文:</summary>
One method
```python
(s0,s1)=arr.strides
np.lib.stride_tricks.as_strided(arr, shape=(3, 2, 2), strides=(s1,0,s0))
Note that it is basically free: it does nothing, and return the same arr
. Just, a change of strides make iterations goes along arr
axis 1 for the new array axis 0; just repeat for axis 1; and along arr
axis 0 for the new array axis 2.
A generalization to all sizes of 2D arr
, and all repetitions
def myrepeat(arr, n):
(sh0,sh1)=arr.shape
(st0,st1)=arr.strides
return np.lib.stride_tricks.as_strided(arr, shape=(sh1,n,sh0), strides=(st1,0,st0))
# Example
arr=np.arange(20).reshape(4,5)
myrepeat(arr,3)
Returns
array([[[ 0, 5, 10, 15],
[ 0, 5, 10, 15],
[ 0, 5, 10, 15]],
[[ 1, 6, 11, 16],
[ 1, 6, 11, 16],
[ 1, 6, 11, 16]],
[[ 2, 7, 12, 17],
[ 2, 7, 12, 17],
[ 2, 7, 12, 17]],
[[ 3, 8, 13, 18],
[ 3, 8, 13, 18],
[ 3, 8, 13, 18]],
[[ 4, 9, 14, 19],
[ 4, 9, 14, 19],
[ 4, 9, 14, 19]]])
</details>
# 答案2
**得分**: 2
[@chrslg][1]的 `stride_tricks` 解决方案可能速度较快,但不容易阅读。相反,我建议使用numpy的 [`np.repeat`][2] 函数,这样可以清晰地表达你的意图。但需要注意的是,你不能直接使用它来获得你想要的结果,首先需要添加另一个维度来分割行。由于这个分割,应该将它应用到 `axis=1` 而不是0。最后的结果需要进行转置以匹配你的需求。
```python
import numpy as np
arr = np.array([[1,2,3], [4,5,6]])
res = np.repeat(arr[:, None, :], 2, axis=1).T
print(res)
输出:
[[[1 4]
[1 4]]
[[2 5]
[2 5]]
[[3 6]
[3 6]]]
英文:
Although @chrslg's stride_tricks
solution might be quick, it is not easily readable. Instead, I'd recommend using the numpy np.repeat
function, which makes it clear what you're doing. That said, you cannot use it directly to get the result you want, you'll first need to add another dimension to split the rows. Because of that split, it should be applied to axis=1
instead of 0. The final result then needs to be transposed to match what you're looking for.
import numpy as np
arr = np.array([[1,2,3], [4,5,6]])
res = np.repeat(arr[:, None, :], 2, axis=1).T
print(res)
Output:
[[[1 4]
[1 4]]
[[2 5]
[2 5]]
[[3 6]
[3 6]]]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论