PythonNet中的Numpy重塑
我正在用pythonnet在C#中使用numpy。我想改变一个数组的形状,但似乎不管怎么做都不行,我也搞不懂为什么。一开始我以为是复杂数组的问题,但后来我用整数试了一下,结果也是一样。
这是我的代码:
using System.Numerics;
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)
];
List<Complex> comlist = new List<Complex>(complexes);
using (Py.GIL())
{
dynamic np = Py.Import("numpy");
dynamic rawData = np.array(comlist);
np.reshape(a: rawData.T, newshape:(2, 2), order:'F');
}
还有错误信息:
Unhandled exception. Python.Runtime.PythonException: expected sequence object with len >= 0 or a single integer
File "C:\Users\Mohsen\AppData\Local\Programs\Python\Python39\lib\site-packages\numpy\core\fromnumeric.py", line 44, in _wrapit
result = getattr(asarray(obj), method)(*args, **kwds)
File "C:\Users\Mohsen\AppData\Local\Programs\Python\Python39\lib\site-packages\numpy\core\fromnumeric.py", line 67, in _wrapfunc
return _wrapit(obj, method, *args, **kwds)
File "C:\Users\Mohsen\AppData\Local\Programs\Python\Python39\lib\site-packages\numpy\core\fromnumeric.py", line 299, in reshape
return _wrapfunc(a, 'reshape', newshape, order=order)
File "<__array_function__ internals>", line 5, in reshape
at Python.Runtime.PythonException.ThrowLastAsClrException()
at Python.Runtime.PyObject.Invoke(PyTuple args, PyDict kw)
at Python.Runtime.PyObject.InvokeMethod(String name, PyTuple args, PyDict kw)
at Python.Runtime.PyObject.TryInvokeMember(InvokeMemberBinder binder, Object[] args, Object& result)
at CallSite.Target(Closure, CallSite, Object, Object, ValueTuple`2, Char)
at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid4[T0,T1,T2,T3](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3)
at Program.<Main>$(String[] args) in C:\Users\Mohsen\RiderProjects\ConsoleApp2\ConsoleApp2\Program.cs:line 29
2 个回答
0
我觉得 numpy
需要的是数字的序列或者序列的序列来处理多维数组,而且它有自己专门的复数数据类型。你用 np.reshape(a: rawData.T, newshape:(2, 2), order:'F')
这种方式来改变数组的形状是对的,参数也没问题,不过 .T
是转置操作的简写。如果你只是想改变数组的形状,其实不一定要先转置。
我们需要把 Complex
对象转换成 numpy
能理解的格式。因为 numpy
有自己的复数类型,所以我们需要把你的 System.Numerics.Complex
数组转换成 numpy
可以处理的格式。一个简单的方法是把每个 Complex
对象转换成一个元组 (实部, 虚部)
,然后让 numpy
来处理这些元组。之后我们可以直接使用改变形状后的数组,或者把它赋值给一个变量。需要注意的是,numpy.reshape
不会直接修改原来的数组,而是会返回一个新的数组。
using System;
using System.Numerics;
using System.Collections.Generic;
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();
}
static void Main(string[] args)
{
Initialize();
Complex[] complexes = new Complex[]
{
new Complex(1.0, 2.0),
new Complex(3.0, 4.0),
new Complex(5.0, 6.0),
new Complex(7.0, 8.0)
};
List<object> comlist = new List<object>();
foreach (var complex in complexes)
{
comlist.Add(new PyTuple(new PyObject[] { new PyFloat(complex.Real), new PyFloat(complex.Imaginary) }));
}
using (Py.GIL()) // Python Global Interpreter Lock is acquired
{
dynamic np = Py.Import("numpy");
dynamic rawData = np.array(comlist, dtype: np.complex);
dynamic reshapedData = np.reshape(rawData, newshape: (2, 2), order: 'F');
Console.WriteLine(reshapedData);
}
}
希望这些对你有帮助。谢谢。
0
要让这个调整大小的功能正常工作,必须使用一个叫做PyTuple的对象。如果不是这样,它就无法正常运作,就是这么简单。