SciSharp / Numpy.NET

C#/F# bindings for NumPy - a fundamental library for scientific computing, machine learning and AI
Other
686 stars 96 forks source link

Error on visualisation of NDArray in dotnet interactive jupyter notebook #103

Open ordinaryorange opened 2 years ago

ordinaryorange commented 2 years ago

Repro code

#r "nuget:Numpy.Bare"
using Numpy;
var nd = np.asarray(new [] {1});
nd

Error: Python.Runtime.PythonException: TypeError : 'numpy.core.multiarray.flagsobj' object is not iterable at Python.Runtime.PyIter..ctor(PyObject iterable) at Python.Runtime.PyObject.GetEnumerator() at System.Linq.Enumerable.CastIterator[TResult](IEnumerable source)+MoveNext() at Microsoft.DotNet.Interactive.Formatting.EnumerableExtensions.TakeAndCountRemaining[T](IEnumerable`1 source, Int32 count, Boolean forceCountRemainder)

Is this something that needs to be adjusted in Numpy.NET or is it a dotnet Interactive thing ?

henon commented 2 years ago

The flags probably would have to be wrapped in a similar manner as NDArray to support enumeration. I have currently no time to work on that though. If you want to improve Numpy.NET integration with dotnet interactive jupyter notebook you are welcome to contribute and I'd answer any questions you'd have along the way.

ordinaryorange commented 2 years ago

Happy to take a look and see if I can contribute. I just briefly browsed through the source to try and see what might be involved, but I got confused quickly. I cant find the flagsobj what is this referring to ? I cant see how NDArray even supports enumeration (inheritance, interfaces, methods), what specifically am I looking at when you say "would have to be wrapped in a similar manner " Also I assume all the work needs to be done in the minion, not the actual source ? Got a 101 here ?

henon commented 2 years ago

Happy to take a look and see if I can contribute. I just briefly browsed through the source to try and see what might be involved, but I got confused quickly.

I cant find the flagsobj what is this referring to ?

I would say you have to find out what method or property of NDArray gets called by the notebook that causes the error. I assume that the returned object which the notebook is trying to enumerate is a python object which we should wrap with a c# facade that supports enumeration.

I cant see how NDArray even supports enumeration (inheritance, interfaces, methods), what specifically am I looking at when you say "would have to be wrapped in a similar manner "

NDarray probably doesn't. Usually you don't enumerate an NDarray. NDArray is a wrapper around the python ndarray object field self to provide a good .NET interface instead of relying on dynamic. Most of this interface is generated by the minion because of the shier volume but some of it is also hand-written to handle special cases.

Also I assume all the work needs to be done in the minion, not the actual source ? Got a 101 here ?

No, not necessarily. Let's assume the notebook is calling a Flags property of NDArray (you have to find out). If so, you add a class Flags and make sure it has the interface the notebook is expecing. Or return a an array of flags or whatever. Of course the implementation would have to forward data to python or get it from python similar to how NDArray is calling into python.

Hope this gets you started. If any more questions arise don't hesitate to ask. If you have any concrete problems I will also directly help you (i.e. by directly pusing into your PR if that is easier than explaining).

Look at the Flags class in Flags.cs. Looks like I already prepared it and maybe you can just extend this class with what the notebook expects. If that is indeed the problem. You need to identify what jupyter notebook calls and expects as return value.