You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取numpy ndarray的非平凡(非连续)视图?

Great question! Let's break this down clearly—first, the key point: you can create non-trivial views of an ndarray only if the new element ordering can be represented by adjusting the array's strides (the byte offsets between elements along each axis) without rearranging the underlying data in memory. For your specific 4D-to-2D reshaping need, this is absolutely feasible, and we can do it safely without copying data.


Solution for Your 4D-to-2D Use Case

Let's start with your sample 4D array:

import numpy as np
x = np.array([[[[1, 1], [1, 1]],[[2, 2], [2, 2]]], [[[3, 3], [3, 3]], [[4, 4], [4, 4]]]])

Your desired view z follows the indexing rule a = u*S + s and b = v*T + t. To get this as a view, we just need to adjust the axis order first, then reshape:

# Rearrange axes to (u, s, v, t) to align with your a/b indexing logic
x_transposed = x.transpose(0, 2, 1, 3)
# Reshape to (U*S, V*T)
z = x_transposed.reshape(4, 4)

Verify this is a view (not a copy):

print(z.flags.owndata)  # Output: False (z doesn't own its data)
print(z.base is x)      # Output: True (z's base is the original array)

And z exactly matches your desired output:

print(z)
# [[1 1 2 2]
#  [1 1 2 2]
#  [3 3 4 4]
#  [3 3 4 4]]

Why This Works

  • Transpose returns a view: When you use transpose, NumPy doesn't copy any data—it just modifies the array's metadata (axis order and strides). For your original array with shape (U, V, S, T), transposing to (U, S, V, T) swaps the positions of the V and S axes, which aligns elements with your a index (u*S + s).
  • Reshape preserves the view: After transposing, reshaping to (U*S, V*T) works as a view because the total number of elements is the same, and NumPy can compute new strides directly from the transposed array's strides. Even though the transposed array is non-contiguous in memory, reshape doesn't require contiguity to return a view.

Answers to Your Other Questions

  • Can you get a view like [2,4,3,1] from [1,2,3,4]? No, you can't. This arbitrary permutation can't be represented with simple stride adjustments—each element's memory address isn't spaced by a consistent offset relative to the previous one. Fancy indexing will always return a copy here, since it has to rearrange data in memory.
  • Why didn't your initial reshape/transpose attempts work? Standard reshape uses C-order (row-major) by default, which flattens your original array as u → v → s → t—this doesn't match your desired a = u*S + s logic. Transposing to (U, S, V, T) first fixes this axis order before reshaping.
  • Is this possible in pure Python? Yes! You don't need C/C++ code—NumPy's built-in transpose and reshape (when used correctly) handle this in pure Python by manipulating the array's metadata (strides and axis order) without touching the underlying data. The ndarray.sort method is in-place because it modifies the original data, not because it's using low-level code—view creation is a separate operation that works by reinterpreting existing data.

A Note on np.as_strided

You mentioned trying as_strided—while it can create custom views, it's risky because it can easily lead to out-of-bounds memory access. For your use case, transpose + reshape is safer and more readable, and it achieves exactly what you need without any risk.

内容的提问来源于stack exchange,提问作者MaxSchambach

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:17:51