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

为何Numpy中取复数数组实部/虚部会导致数组非C连续?

Why does accessing the real/imaginary part of a NumPy complex array result in a non-contiguous array?

Great question! This isn't a bug—it's intentional behavior tied to how NumPy stores complex arrays and handles views vs. copies. Let's break it down:

How NumPy stores complex arrays

NumPy uses an interleaved storage format for complex arrays. That means for an array like y = np.exp(1j*t), the memory layout looks like this:
[re0, im0, re1, im1, re2, im2, ..., ren-1, imn-1]
Each complex number's real and imaginary parts are stored back-to-back, rather than having a single block of all real parts followed by a block of all imaginary parts.

Why y.real is non-contiguous

When you access y.real, NumPy doesn't create a new array by copying all the real parts into a continuous block of memory. Instead, it returns a view of the original array. This view uses a stride (the number of bytes to jump between elements) that skips the imaginary parts: for a complex128 array, each real element is 8 bytes, but the stride between consecutive real elements is 16 bytes (since each complex number takes 16 bytes total).

Because the view doesn't occupy a single continuous block of memory (it's skipping every other element in the original array), y.real.flags will show C_CONTIGUOUS = False.

Why abs(y) and angle(y) are contiguous

In contrast, functions like np.abs(y) and np.angle(y) compute a new value for each element and return a new, independent array. This new array is stored as a continuous block of memory (just like any standard floating-point array you'd create from scratch), so their flags will show C_CONTIGUOUS = True.

When you use np.cos(np.angle(y)), you're essentially creating two new continuous arrays in sequence: first angle(y) generates a continuous array, then cos() operates on that to produce another continuous array of real parts.

How to get a contiguous real/imaginary part array

If you need a contiguous version of the real or imaginary parts, you have a few options:

  • Explicitly copy the view to a new array: y_real_contiguous = y.real.copy()
  • Use np.ascontiguousarray() to convert the view to a contiguous array: y_real_contiguous = np.ascontiguousarray(y.real)
  • Precompute real and imaginary parts separately (avoids the view entirely): y_real = np.cos(t); y_imag = np.sin(t)

Example code to verify

import numpy as np

t = np.linspace(0, 10)
y = np.exp(1j * t)

print("Original array flags:")
print(y.flags, "\n")

print("y.real flags (non-contiguous view):")
print(y.real.flags, "\n")

print("abs(y) flags (contiguous new array):")
print(np.abs(y).flags, "\n")

# Convert to contiguous array
y_real_contiguous = np.ascontiguousarray(y.real)
print("Contiguous y.real flags:")
print(y_real_contiguous.flags)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:34:52