使用pythonnet在C#中调用NumPy fftn时遇复数输入错误
解决PythonNet中C#复数数组转numpy时FFT报错问题
问题核心在于:C#的System.Numerics.Complex对象无法被PythonNet自动映射为numpy的原生复数类型。直接将C#复数列表传入np.array()时,numpy会把每个元素识别为自定义CLR对象,而非原生复数,导致FFT函数误判输入类型并抛出错误。
解决方案
手动将C#复数的实部和虚部分离,构造numpy可识别的原生复数数组:
- 提取C#复数序列的实部、虚部,分别转为浮点数组
- 利用numpy的复数构造规则,将实部和虚部组合为
complex128类型的数组
修改后的完整代码
using System.Globalization; using System.Net.Mime; using System.Numerics; using System.Linq; using Python.Runtime; static void Initialize() { string pythonDll = @"C:\Users\Mohsen\AppData\Local\Programs\Python\Python39\python39.dll"; Environment.SetEnvironmentVariable("PYTHONNET_PYDLL", pythonDll); PythonEngine.Initialize(); } Initialize(); Complex[] complexes = [ new Complex(1.0, 2.0), new Complex(3.0, 4.0), new Complex(5.0, 6.0), new Complex(5.0, 6.0) ]; using (Py.GIL()) { dynamic lst = new PyList(); lst.append(2); lst.append(2); dynamic tuple = PyTuple.AsTuple(lst); dynamic np = Py.Import("numpy"); // 关键修改:手动构造numpy原生复数数组 double[] realParts = complexes.Select(c => c.Real).ToArray(); double[] imagParts = complexes.Select(c => c.Imaginary).ToArray(); dynamic rawData = np.array(realParts, dtype: np.float64) + 1j * np.array(imagParts, dtype: np.float64); rawData.reshape(tuple); dynamic k = np.reshape(a: rawData.T, newshape:tuple, order:'F'); k = np.fft.fftshift(k); k = np.fft.fftn(k); k = np.fft.fftshift(k); k = np.rot90(k); k = np.flip(k, axis : 0); k = np.flip(np.rot90(np.fft.fftshift(np.fft.fftn(np.fft.fftshift(k))))); Console.WriteLine(k.shape); }
关键说明
- 通过分离实部和虚部并组合为numpy原生复数,确保数组的
dtype为complex128,完全匹配numpy FFT函数的输入要求 - 规避了PythonNet自动转换CLR对象时的类型不兼容问题
内容的提问来源于stack exchange,提问作者noobie
相关产品推荐
相关产品推荐

