2

I know how to get a slice from a Numpy array using the C API this way:

    // 'arr' is a 2D Python array, already created
    PyObject pyArray = PyArray_FromAny(arr, PyArray_DescrFromType(NPY_FLOAT), 0, 0, NPY_ARRAY_DEFAULT, null);

    PyObject slice = PySlice_New(PyLong_FromLong(0), PyLong_FromLong(2), null);
    PyObject result = PyObject_GetItem(pyArray, slice);

This basically matches the following Python expression:

    arr[0:2]

Now, how can I get a "multi" slice from 'arr'? For instance, how can programmatically write the following expression?

    arr[0:2,0:3]
11
  • I'm not sure and cannot test it, but can you try to create a tuple of slices and call GetItem passing the tuple? Commented Mar 13, 2020 at 8:57
  • Slice creation works fine with two tuples (instead of two integers), with both tuples containing two integers. Calling PyObject_GetItem with these tuples results in the following error: TypeError: slice indices must be integers or None or have an index method Commented Mar 13, 2020 at 9:18
  • Sorry but maybe I was not clear: create the two slices PyObject slice_a = PySlice_New(PyLong_FromLong(0), PyLong_FromLong(2), null); and PyObject slice_b = PySlice_New(PyLong_FromLong(0), PyLong_FromLong(3), null);, then create a tuple like PyObject tuple = PyTuple_Pack(2, slice_a, slice_b) and then call PyObject result = PyObject_GetItem(pyArray, tuple); Commented Mar 13, 2020 at 9:27
  • My apology. I tried what you said, GetItem does succeed, but I get a crash when trying to print the result with: PyDict_SetItemString(globals, "result", result); PyRun_SimpleStringFlags("print(result, flush=True)", null); (printing code succeeds when my slice is 1D) Commented Mar 13, 2020 at 9:31
  • The rationale behind this is that the __getitem__ in python(3) has signature __getitem__(self, key) and it is "not allowed" __getitem__(self, key_1, key_2), thus in array[0:2,0:3] I suspect it is actually array.__getitem__(self,key = (slice(0,2), slice(0,3))) Commented Mar 13, 2020 at 9:33

1 Answer 1

2

In order to get multi dimensional slices you have to insert the slices in a tuple, the call the get item on that tuple. Something like:

PyObject* pyArray = PyArray_FromAny(arr, PyArray_DescrFromType(NPY_FLOAT), 0, 0, NPY_ARRAY_DEFAULT, null);

PyObject* slice_0 = PySlice_New(PyLong_FromLong(0), PyLong_FromLong(2), null);
PyObject* slice_1 = PySlice_New(PyLong_FromLong(0), PyLong_FromLong(3), null);
PyObject* slices = PyTuple_Pack(2, slice_0, slice_1);

PyObject* result = PyObject_GetItem(pyArray, slices);

The rationale behind it is the __getitem__(self, arg) (there is a single argument) thus multiple indexes are implicitly converted in a tuple: arg = (slice(0,2), slice(0,3),)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.