栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

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

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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


总的来说,事实证明,使用正确的工具,用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,然后在第48行中通过提供JDK路径来修改
setup.py 脚本:

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还是服务器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 classjpype.java.lang.System.out.println ('Berlusconi likes women') jpype.shutdownJVM()

也使用Numpy从Java调用Java类

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

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<the_array.length;i++){        result=result+the_array[i];    }    return result/the_array.length;}// multiplies array by a scalarpublic static double[] multiply(double[] the_array, double factor) {    int i;    double[] the_result= new double[the_array.length];    for (i=0;i<the_array.length;i++) {        the_result[i]=the_array[i]*factor;    }    return the_result;}public static double[][] mult_mat(double[][] mat1, double[][] mat2){    // find sizes    int n1=mat1.length;    int n2=mat2.length;    int m1=mat1[0].length;    int m2=mat2[0].length;    // check that we can multiply    if (n2 !=m1) {        //System.err.println("Error: The number of columns of the first argument must equal the number of rows of the second");        //return null;        throw new IllegalArgumentException("Error: The number of columns of the first argument must equal the number of rows of the second");    }    // if we can, then multiply    double[][] the_results=new double[n1][m2];    int i,j,k;    for (i=0;i<n1;i++){        for (j=0;j<m2;j++){ // initialize the_results[i][j]=0; for (k=0;k<m1;k++) {     the_results[i][j]=the_results[i][j]+mat1[i][k]*mat2[k][j]; }        }    }    return the_results;}public static void main(String[] args) {    // test case    double an_array[]={1.0, 2.0,3.0,4.0};    double res=Average2.compute_average(an_array);    System.out.println("Average is =" + res);}}

该类的名称有点令人误解,因为我们不仅旨在计算numpy向量的平均值(使用方法 compute_average ),而且还将numpy向量与标量 相乘
(方法 乘法 ),最后将矩阵相乘乘法(方法 mult_mat )。

编译完上述Java类之后,我们现在可以运行以下Python脚本:

import numpy as npimport jpypejvmPath = jpype.getDefaultJVMPath() # we to specify the classpath used by the JVMclasspath='/home/mannaggia/workspace/TestJava/bin'jpype.startJVM(jvmPath,'-Djava.class.path=%s' % classpath)# numpy arraythe_array=np.array([1.1, 2.3, 4, 6,7])# build a JArray, not that we need to specify the Java double type using the jpype.JDouble wrapperthe_jarray2=jpype.JArray(jpype.JDouble, the_array.ndim)(the_array.tolist())Class_average2=testPkg.Average2 res2=Class_average2.compute_average(the_jarray2)np.abs(np.average(the_array)-res2) # ok perfect match!# now try to multiply an arrayres3=Class_average2.multiply(the_jarray2,jpype.JDouble(3))# convert to numpy arrayres4=np.array(res3) #ok# matrix multiplicationthe_mat1=np.array([[1,2,3], [4,5,6], [7,8,9]],dtype=float)#the_mat2=np.array([[1,0,0], [0,1,0], [0,0,1]],dtype=float)the_mat2=np.array([[1], [1], [1]],dtype=float)the_mat3=np.array([[1, 2, 3]],dtype=float)the_jmat1=jpype.JArray(jpype.JDouble, the_mat1.ndim)(the_mat1.tolist())the_jmat2=jpype.JArray(jpype.JDouble, the_mat2.ndim)(the_mat2.tolist())res5=Class_average2.mult_mat(the_jmat1,the_jmat2)res6=np.array(res5) #ok# other testthe_jmat3=jpype.JArray(jpype.JDouble, the_mat3.ndim)(the_mat3.tolist())res7=Class_average2.mult_mat(the_jmat3,the_jmat2)res8=np.array(res7)res9=Class_average2.mult_mat(the_jmat2,the_jmat3)res10=np.array(res9)# test error due to invalid matrix multiplicationthe_mat4=np.array([[1], [2]],dtype=float)the_jmat4=jpype.JArray(jpype.JDouble, the_mat4.ndim)(the_mat4.tolist())res11=Class_average2.mult_mat(the_jmat1,the_jmat4)jpype.java.lang.System.out.println ('Goodbye!') jpype.shutdownJVM()


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/407118.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号