Cannot slice by passing either a string or a Numpy.Models.Slice as an index.
megawattfs opened this issue · 6 comments
I am using Numpy.dll version 3.10.1.30 with Python.Runtime.dll version 2.5.2. When I try slicing a 1d NDarray I get a MissingMethodException. Here is my code:
using Numpy;
using static Numpy.np;
using System.Numerics;
using Numpy.Models;
using Python.Runtime;
public static void numpy_test()
{
Python.Runtime.PythonEngine.Initialize();
NDarray arr = np.array(new float[]{ 1, 2, 3, 4, 5 });
Numpy.Models.Slice slice0 = new Numpy.Models.Slice(2, 4);
var arr4 = arr[slice0];
Numpy.Models.Slice slice1 = new Numpy.Models.Slice(2, -1);
var arr5 = arr[slice1];
var arr1 = arr["2:4"];
var arr2 = arr[":4"];
var arr3 = arr[":-1"];
Debug.Log("Numpy test passed.");
}
As far as I can tell the syntax is as described in the README; however, none of the slicing operations in the above method work (I tested each of them individually). Indexing with a single value (arr[0]
) works, but I haven't figured out a way to do slicing.
Stack trace back to my test method:
System.MissingMethodException: Python.Runtime.PyObject Python.Runtime.PythonEngine.Eval(string,Python.Runtime.PyDict,Python.Runtime.PyObject) at Numpy.PythonObject.ToPython (System.Object obj) [0x0014d] in <b8b5aebdcf44433497e62f392cbc5b60>:0 at Numpy.NDarray.<get_Item>b__71_0 (System.Object x) [0x00080] in <b8b5aebdcf44433497e62f392cbc5b60>:0 at System.Linq.Enumerable+SelectArrayIterator2[TSource,TResult].ToArray () [0x00012] in <351e49e2a5bf4fd6beabb458ce2255f3>:0 at System.Linq.Enumerable.ToArray[TSource] (System.Collections.Generic.IEnumerable1[T] source) [0x0001f] in <351e49e2a5bf4fd6beabb458ce2255f3>:0 at Numpy.NDarray.get_Item (System.Object[] arrays_slices_or_indices) [0x00012] in <b8b5aebdcf44433497e62f392cbc5b60>:0 at FilteringUtility.numpy_test () [0x00031]
Update: I have tried to dig into this issue by copying the slicing by string code over from NDarray.cs to figure out why it breaks down:
using Numpy;
using static Numpy.np;
using System.Numerics;
using Numpy.Models;
using Python.Runtime;
public static void numpy_test()
{
Python.Runtime.PythonEngine.Initialize();
NDarray arr = np.array(new float[]{ 1, 2, 3, 4, 5 });
var tuple = new PyTuple(Numpy.Models.Slice.ParseSlices("2:4").Select(s =>
{
if (s.IsIndex)
return new PyInt(s.Start.Value);
else
return s.ToPython();
}).ToArray());
var arr0 = new NDarray(arr.PyObject[tuple]);
Debug.Log("Numpy test passed.");
}
But this does not compile because "The type 'PyObject' is defined in an assembly that is not referenced. You must add a reference to assembly 'Python.Runtime, Version=3.0.0.0, Culture=neutral, PublicKeyToken=5000fea6cba702dd'."
But the most recent version of Python.Runtime available on NuGet is 2.5.2, which does have a definition for Python.Runtime.PyObject, as does Numpy.Models. Not sure what is going on here but will keep looking into it.
I just added a little test case with your code and it works perfectly in my test environment.
[TestMethod]
public void IssueByMegawattFs()
{
var arr = np.array(new int[] { 1, 2, 3, 4, 5 });
var slice0 = new Slice(2, 4);
var arr4 = arr[slice0];
Assert.AreEqual("array([3, 4])", arr4.repr);
var slice1 = new Slice(2, -1);
var arr5 = arr[slice1];
Assert.AreEqual("array([3, 4])", arr5.repr);
var arr1 = arr["2:4"];
Assert.AreEqual("array([3, 4])", arr1.repr);
var arr2 = arr[":4"];
Assert.AreEqual("array([1, 2, 3, 4])", arr2.repr);
var arr3 = arr[":-1"];
Assert.AreEqual("array([1, 2, 3, 4])", arr3.repr);
}
Here are the dependencies of my test project:
As you can see the difference is that Numpy references pythonnet 3.0.0-preview2022-04-11
I don't understand why yours uses Python.Runtime.dll version 2.5.2
. I'll make a test project with the nuget to see if there is something wrong with the numpy 3.10.1.30 nuget.
I see what happened:
I am using Unity, which is not compatible with NuGet. My process for adding Numpy to my project was as follows:
- Download the .nupkg directly from the NuGet website.
- Look under "Dependencies" on the NuGet page and download the .nupkg for all the dependencies
- Repeat step 2 with the NuGet page for all the dependencies until there are none left
- Extract the .nupkg files and add the .NET Standard 2 version of each package to my Unity project assets folder.
On the NuGet page for Numpy, Python.Runtime is not even listed as a dependency:
Therefore, I determined which version of Python.Runtime to use based on Python.Included, which lists Python.Runtime v2.5.2 as the minimum requirement and links to this download:
I see now that there is a version 3.0.0 available at https://www.nuget.org/packages/pythonnet/3.0.0-rc4. I will try that and see if it works. Maybe this version should be listed under dependencies for Numpy on the NuGet page?
Thank you for looking into this!
Never mind--I see now that I was using the wrong version of Python.Included (I got mixed up because NuGet linked me to the "latest" non-preview version of Python.Included from Numpy's dependency page, but I needed 3.10.0-preview2).
Correct ;). Closing this. Should you still have issues you can reopen.