Numpy Reshape in PythonNet

37 Views Asked by At

I'm using pythonnet to use numpy in c#. I want to reshape an array but it seems to not work and I cant seem to understand why. at first i thought there was a problem with the complex array but then i tried it with int and it was the same

here is the code

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');
}

and the error message:

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

There are 2 best solutions below

1
noobie On

The reshape size must be a PyTuple object for it to work other wise it doesnt so thats that.

0
Dowjones On

I think numpy expects sequences of numbers or sequences of sequences for multidimensional arrays, and it has its own data type for complex numbers. The way you're trying to reshape the array using np.reshape(a: rawData.T, newshape:(2, 2), order:'F') is correct in terms of function parameters, but .T is a shorthand for the transpose operation. If your intention was just to reshape the array, you don't necessarily need to transpose it first.

We should convert the Complex objects to a numpy-understandable format. Since numpy has its own complex number type, we need to convert your System.Numerics.Complex array to a format numpy can work with. A straightforward way is to convert each Complex object to a tuple (real, imaginary) and then let numpy handle these tuples. Then we will use the reshaped array directly or assign it to a variable. numpy.reshape doesn't modify the array in place; instead, it returns a new array.

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);
    }
}

Hope it helps. Thanks.