Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Weird behavior of casting nd.ndarray on different types #2407

Copy link
Copy link
@Trippley

Description

@Trippley
Issue body actions

Environment

  • Pythonnet version: 3.0.3
  • Python version: 3.12.4
  • Operating System: Windows 11 23H2
  • .NET Runtime: net8.0
  • numpy Version: 2.0.0

Details

  • Describe what you were trying to get done.

    I am currently migrating from an older undefined pythonnet Version to 3.0.3 with an corresponding upgrade of python from 3.7.9 to 3.12.4.

    We had some C# logic in place which executed python code and took the result of Tuple[nd.ndarray(dtype=int), nd.ndarray(dtype=float)] and converted it from dynamic to concrete types.

I am experiencing issues while converting the nd.ndarray(dtype=int) via (long[])result[0]

---- System.Exception : Cannot convert to System.Int64 array
-------- Microsoft.CSharp.RuntimeBinder.RuntimeBinderException : Cannot convert type 'Python.Runtime.PyObject' to 'long[]'

The nd.ndarray(dtype=float) via (double[])result[1] works as a charme.
Same as when I both return as dtype=float and convert them to double.

My current workaround is iterating over the nd.ndarray(dtype=int) with the size of the result array by calling ToArrayByIteration()

Am I missing something?

Problematic here is converting "indices" from dtype=int to long in C#. The datatype of the result in C# in Debug view seems to be Int64.

    @staticmethod
    def method(rate: int, data: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
        ds = int(rate)
        indices = np.arange(len(data), dtype=int)
        result_data = np.array(data, dtype=float)

        n = len(indices )
        indices = indices [:n * ds:ds]
        result_data = result_data [:n * ds].reshape(n, ds).mean(axis=1)

        return indices , result_data 

Returning dtype=float is not intended but works with the same conversion to double.

    @staticmethod
    def method(rate: int, data: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
        ds = int(rate)
        indices = np.arange(len(data), dtype=float)
        result_data = np.array(data, dtype=float)

        n = len(indices )
        indices = indices [:n * ds:ds]
        result_data = result_data [:n * ds].reshape(n, ds).mean(axis=1)

        return indices , result_data 

I left out initialising pythonengine and loading the module in this case.

public class Wrapper 
{
    public (long[] x, double[] y) ExecutePythonMethod(
    int rate,
    List<double> data)
    {
        using var _ = Py.GIL();
        var result = _module.class.method(rate, data);

        var x = PythonDataConverter.ToArrayByIteration<long>(result[0]);
        var y = PythonDataConverter.ToArray<double>(result[1]);
        return (x, y);
    }
}

public static class PythonDataConverter
{
    public static T[] ToArrayByIteration<T>(dynamic arrayFromPython)
    {
        var size = (long)arrayFromPython.size;

            var array = new T[size];

            for (var i = 0; i < size; i++)
            {
                array[i] = (T)arrayFromPython[i];
            }

            return array;
    }

    public static T[] ToArray<T>(dynamic arrayFromPython)
    {
            return (T[])arrayFromPython;
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.