ninia / jep

Embed Python in Java
Other
1.27k stars 146 forks source link

dimension lost when get numpy return from python script #532

Closed githubbbbber closed 2 months ago

githubbbbber commented 2 months ago

In the Python code, I returned my result as follows:

ret = {"img": img}

img is a NumPy array. In the Java runtime, I wrote my Java code as follows:

Object result = interpreter.invoke("main", new Object[]{inputMap});

But I receive a 1-dimensional byte array named img, and the NumPy shape is lost. I can't pass it to another Python code as a NumPy array. Is there any best practice or JEP data structure that can solve this problem?

bsteffensmeier commented 2 months ago

It looks like your version of jep was compiled without numpy support. You will need to rebuild jep with numpy for more advanced conversions. You can check if your build of jep has numpy support by looking at the JEP_NUMPY_ENABLED attribute of the jep python module. In order to build jep with numpy support, numpy must be installed on the system when the jep module is built. This is necessary because jep uses native code and headers from numpy to support advanced conversion and these are not available when numpy is not installed.

Here is a sample program I used on my system to simulate your problem and verify that it is possible to get the numpy shape when jep is built with numpy support.

    public static void main(String[] args) throws JepException {
        try (SharedInterpreter interpreter = new SharedInterpreter()) {
            interpreter.exec("import jep");
            interpreter.exec("print('numpy enabled =', jep.JEP_NUMPY_ENABLED)");
            interpreter.exec("import numpy");
            interpreter.exec("def main():\n    return {'img': numpy.ndarray((1,2,3))}");
            Object result = interpreter.invoke("main");
            Object img = ((Map) result).get("img");
            System.out.println(img.getClass());
            int[] dimensions = ((NDArray) img).getDimensions();
            System.out.println(Arrays.toString(dimensions));
       }
    }

Running this results in the following output on my system:

numpy enabled = 1 class jep.NDArray [1, 2, 3]

githubbbbber commented 2 months ago

It looks like your version of jep was compiled without numpy support. You will need to rebuild jep with numpy for more advanced conversions. You can check if your build of jep has numpy support by looking at the JEP_NUMPY_ENABLED attribute of the jep python module. In order to build jep with numpy support, numpy must be installed on the system when the jep module is built. This is necessary because jep uses native code and headers from numpy to support advanced conversion and these are not available when numpy is not installed.

Here is a sample program I used on my system to simulate your problem and verify that it is possible to get the numpy shape when jep is built with numpy support.

    public static void main(String[] args) throws JepException {
        try (SharedInterpreter interpreter = new SharedInterpreter()) {
            interpreter.exec("import jep");
            interpreter.exec("print('numpy enabled =', jep.JEP_NUMPY_ENABLED)");
            interpreter.exec("import numpy");
            interpreter.exec("def main():\n    return {'img': numpy.ndarray((1,2,3))}");
            Object result = interpreter.invoke("main");
            Object img = ((Map) result).get("img");
            System.out.println(img.getClass());
            int[] dimensions = ((NDArray) img).getDimensions();
            System.out.println(Arrays.toString(dimensions));
       }
    }

Running this results in the following output on my system:

numpy enabled = 1 class jep.NDArray [1, 2, 3]

@bsteffensmeier Thank you very much. I rebuilt jep with numpy and the problem is solved now.https://github.com/ninia/jep/issues/490 also helped a lot.