Numpy的”tile”用于复杂转换。

huangapple go评论76阅读模式
英文:

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]]]

huangapple
  • 本文由 发表于 2023年6月26日 23:34:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76558177.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定