如何从python / numpy调用java函数?

我很清楚如何使用C ++扩展Python,但是如果我想在Java中编写一个与numpy一起使用的函数呢?

这是一个简单的场景:我想使用Java类计算numpy数组的平均值。 如何将numpy向量传递给Java类并收集结果?

谢谢你的帮助!

我花了一些时间在我自己的问题上,并希望分享我的答案,因为我觉得在stackoverflow上关于这个主题的信息不多。 我还认为Java将在科学计算中变得更加相关(例如,参见用于数据挖掘的WEKA包),因为Java的性能和其他良好的软件开发function得到了改进。


一般来说,使用正确的工具,使用Java扩展Python比使用C / C ++更容易!


概述和评估从Python调用Java的工具

  • http://pypi.python.org/pypi/JCC :由于没有适当的文档,这个工具没用。

  • Py4J:需要在使用python之前启动Java进程。 正如其他人所说,这是一个可能的失败点。 此外,没有记录很多使用的例子。

  • JPype :虽然开发似乎是死亡,但它运作良好,网上有很多例子(例如参见http://kogs-www.informatik.uni-hamburg.de/~meine/weka-python/使用用Java编写的数据挖掘库)。 因此我决定专注于这个工具

在Fedora 16上安装JPype

我正在使用Fedora 16,因为在Linux上安装JPype时存在一些问题,我描述了我的方法。 下载JPype ,然后通过提供JDK路径修改setup.py脚本,在第48行:

self.javaHome = '/usr/java/default' 

然后运行:

 sudo python setup.py install 

安装成功后,请检查此文件:

/usr/lib64/python2.7/site-packages/jpype/_linux.py

并将方法getDefaultJVMPath()删除或重命名为getDefaultJVMPath_old() ,然后添加以下方法:

 def getDefaultJVMPath(): return "/usr/java/default/jre/lib/amd64/server/libjvm.so" 

替代方法 :不要对上面的文件_linux.py进行任何更改,但绝不使用方法getDefaultJVMPath()(或调用此方法的方法)。 在使用getDefaultJVMPath()的地方直接提供JVM的路径。 请注意,有几个路径,例如在我的系统中,我也有以下路径,指的是不同版本的JVM(我不清楚客户端或服务器JVM是否更适合):

  • /usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre/lib/x86_64/client/libjvm.so
  • /usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre/lib/x86_64/server/libjvm.so
  • /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/amd64/server/libjvm.so

最后, 将以下行添加到〜/ .bashrc (或在每次打开python解释器之前运行它):

 export JAVA_HOME='/usr/java/default' 

(上面的目录实际上只是我上一版JDK的符号链接,它位于/usr/java/jdk1.7.0_04 )。

请注意,已下载JPype的目录中的所有测试,即JPype-0.5.4.2 / test / testsuite.py都将失败(因此不关心它们)。

要查看它是否有效,请在python中测试此脚本:

 import jpype jvmPath = jpype.getDefaultJVMPath() jpype.startJVM(jvmPath) # print a random text using a Java class jpype.java.lang.System.out.println ('Berlusconi likes women') jpype.shutdownJVM() 

使用Numpy从Java调用Java类

让我们开始实现一个包含一些我想要应用于numpy数组的函数的Java类。 由于没有状态概念,我使用静态函数,因此我不需要创建任何Java对象(创建Java对象不会改变任何东西)。

 /** * Cookbook to pass numpy arrays to Java via Jpype * @author Mannaggia */ package test.java; public class Average2 { public static double compute_average(double[] the_array){ // compute the average double result=0; int i; for (i=0;i
		      	

我认为Jython是最好的选择之一 – 这使得在python中使用java对象变得无缝。 我实际上将weka与我的python程序集成在一起,这非常简单。 只需导入weka类并像在python代码中的java中那样调用它们。

http://www.jython.org/

我不确定numpy支持,但以下可能会有所帮助:

http://pypi.python.org/pypi/JCC/