17

我想创建numpy.ndarray包含复杂整数值的对象。NumPy 确实具有内置的复杂支持,但仅适用于浮点格式(floatdouble);例如,我可以创建一个ndarraywith dtype='cfloat',但没有类似dtype='cint16'的 . 我希望能够创建包含使用 8 位或 16 位整数表示的复杂值的数组。

我发现了 2007 年的这个邮件列表帖子,有人询问了这种支持。他们推荐的唯一解决方法是定义一个dtype包含整数对的新方法。这似乎将每个数组元素表示为 2 个值的元组,但尚不清楚需要完成哪些其他工作才能使生成的数据类型与算术函数无缝协作。

我还考虑了另一种基于使用 NumPy注册用户定义类型的方法。如果它运行良好,我没有问题去 C API 进行设置。但是,类型描述符结构的文档似乎表明该类型的kind字段仅支持有符号/无符号整数、浮点和复数浮点数字类型。目前尚不清楚我能否在任何地方尝试定义复杂的整数类型。

关于可能有效的方法的任何建议?

编辑:还有一件事;我选择的任何方案都必须能够在不执行复制的情况下包装现有的复杂整数缓冲区。也就是说,我希望能够使用PyArray_SimpleNewFromData()将缓冲区公开给 Python,而不必先复制缓冲区。缓冲区已经是交错的实数/虚数格式,并且可以是int8_t或的数组int16_t

4

3 回答 3

14

我还处理大量复杂的整数数据,通常是基带数据。我用

dtype = np.dtype([('re', np.int16), ('im', np.int16)])

它并不完美,但它充分描述了数据。我用它来加载到内存中而不会使数据的大小加倍。它还具有能够使用 HDF5 透明地加载和存储的优势。

DATATYPE  H5T_COMPOUND {
    H5T_STD_I16LE "re";
    H5T_STD_I16LE "im";
}

使用它很简单,只是不同。

x = np.zeros((3,3),dtype)
x[0,0]['re'] = 1
x[0,0]['im'] = 2
x
>> array([[(1, 2), (0, 0), (0, 0)],
>>        [(0, 0), (0, 0), (0, 0)],
>>        [(0, 0), (0, 0), (0, 0)]], 
>>  dtype=[('re', '<i2'), ('im', '<i2')])

为了用它做数学,我转换为原生的复杂浮点类型。显而易见的方法不起作用,但也没有那么难。

y = x.astype(np.complex64) # doesn't work, only gets the real part
y = x['re'] + 1.j*x['im']  # works, but slow and big
y = x.view(np.int16).astype(np.float32).view(np.complex64)
y
>> array([[ 1.+2.j,  0.+0.j,  0.+0.j],
>>        [ 0.+0.j,  0.+0.j,  0.+0.j],
>>        [ 0.+0.j,  0.+0.j,  0.+0.j]], dtype=complex64)

最后一种转换方法的灵感来自https://stackoverflow.com/a/5658446/1784179

于 2015-09-30T23:37:46.637 回答
1

您是否考虑过使用 [[a,-b],[b,a]] 形式的矩阵来代替复数?矩阵的普通乘法和加法对应于加法和复数的乘法(这个 2x2 矩阵集合的子环与复数同构)。我认为python可以处理整数矩阵代数。

于 2020-10-22T16:24:35.467 回答
-1

Python 和 Numpy 确实支持复数,如果你想要复数,只需使用 np.round 或忽略小数部分。

例如

import numpy as np
#Create 100 complex numbers in a 1D array
a=100*np.random.sample(100)+(100*np.random.sample(100)*1j)
#Reshape to a 2D array
np.round(a)
a.reshape(10,10)

#Get the real and imag parts of a couple x/y points as integers
print int(a[1:2].real)
print int(a[3:4].imag)
于 2013-02-07T13:49:27.470 回答