java 调用 python脚本并传递参数list

项目需求:需要java调用python脚本,而且需要向脚本中传递参数,经过很长时间的摸索之后研究出了点东西,因为实在没有老师教,所以只能摸索出了最笨的方法,现在记录下来,希望大家有好的方法多多指教。

1、执行单行代码,使用Jython

        
		
		
			org.python
			jython-standalone
			2.7.1
		
/**
     * 执行单行代码
     */
    @Test
    public void test1_code(){
        PythonInterpreter pythonInterpreter=new PythonInterpreter();
        pythonInterpreter.exec("print('-----执行单行代码:Hello')");
    }

2、执行文件脚本,有函数名不带参数,而且不引用三方库,使用Jython

hello.py:

def hello():
    return '----py文件执行结果:Hello'
/**
     * 执行文件脚本,有函数名不带参数,不使用三方库
     */

    @Test
    public void test2_file(){
        PythonInterpreter pythonInterpreter=new PythonInterpreter();
        //注意这边要用绝对路径
        pythonInterpreter.execfile("E:\\mlthfs\\src\\main\\resources\\pythonDemo\\hello.py");
        //第一个参数为期望获得的函数(变量)的名字,第二个参数为期望返回的对象类型
        PyFunction pyFunction=pythonInterpreter.get("hello",PyFunction.class);
        //调用函数,此时call无参数
        PyObject pyObject=pyFunction.__call__();
        System.out.println(pyObject);
    }

3、执行文件脚本,由函数名,带参数,不用三方库,Jython

testWithParam.py:

def my_test(name, age):
    print("name: "+name)
    print("age: "+age)
    return "success"
 /**
     * 执行文件脚本,由函数名,带参数
     */
    @Test
    public void test3_Param(){
        PythonInterpreter interpreter=new PythonInterpreter();
        interpreter.execfile("E:\\mlthfs\\src\\main\\resources\\pythonDemo\\testWithParam.py");
        PyFunction pyFunction=interpreter.get("my_test",PyFunction.class);
        //调用函数,此时call传入两个参数
        PyObject pyObject=pyFunction.__call__(new PyString("tom"),new PyString("25"));
        System.out.println(pyObject.toString());
    }

4、调用脚本,使用三方库,传递参数list,脚本接收一维数组,

说明一下,python脚本中需要接收两个一维数组作为数据输入,我的思路是从java中传入list,然后再在ppython中做处理将传进去的参数转为数组,进行运算。

传参数的时候只能将所有的参数组合成一个字符串,实质是cmd命令行。

接收的时候使用sys.argv方法接收脚本外传入的参数,并且组成一个列表list,第一个元素是命令行,从第二个开始就是传入的list参数,使用print(sys.argv[1:])打印出来就是:

sys.argv[1:]== ['[3340,', '4525,', '7304,', '3335,', '5319,', '5319,', '3932,', '3932,', '4]']

现在看来格式很乱。需要根据需要处理:具体在脚本中体现,不一一赘述。

 Process process = Runtime.getRuntime().exec(
                    pythonPath + filePath + list1);
public void test6_ThirdPackage_param()  {
        String pythonPath="D:\\Program Files\\Python\\Python36\\python.exe ";
        String filePath="E:\\mlthfs\\src\\main\\resources\\pythonDemo\\test7.py ";

        //首先定义两个list,赋值。
        List list1 = new ArrayList<>();
        List list2 = new ArrayList<>();
        Integer list1Size=null;
        //给list1赋值
        list1.add(3340);
        list1.add(4525);
        list1.add(7304);
        list1.add(3335);
        //给list2赋值
        list2.add(5319);
        list2.add(5319);
        list2.add(3932);
        list2.add(3932);
        //得到第一个list的size,传入脚本中,方便分割参数
        list1Size=list1.size();
        System.out.println("list1-size()"+list1.size());
        //将list1.list2合并
        list1.addAll(list2);
        //将size加到list1最后
        list1.add(list1Size);

        try {
            Process process = Runtime.getRuntime().exec(
                    pythonPath + filePath + list1);
            BufferedReader in=new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line=in.readLine())!=null){
                System.out.println(line);
            }
            in.close();
            int re=process.waitFor();
            System.out.println(re==1?"----状态码1----运行失败":"----状态码0----运行成功");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

py脚本:

import sys

# 评估指标
def MetricsValue(yobs,yfit):
    import numpy as np
    yyobs=np.array(yobs)
    yyfit=np.array(yfit)
    data =[yyobs, yyfit]
    R=np.corrcoef(data) [0,1]              # 相关系数

    # 预报的变幅误差
    yo_yp=yyfit-yyobs
    BFWC=yo_yp/np.ptp(yyobs)
    V10 = np.size(np.where((abs(BFWC) <= 0.1)))/np.size(yyobs)  # 非常要注意这个括号 没有括号估计内部执行顺序不对
    V20 = np.size(np.where((abs(BFWC) <=0.2))) / np.size(yyobs)

    # 确定性系数
    D1=np.sum(yo_yp**2)
    D2=np.sum((yyobs-np.mean(yyobs))**2)
    D=1-D1/D2

    #均方根误差RMSe
    Rmse1=sum(yo_yp**2)
    Rmse=np.sqrt(Rmse1/np.size(yyobs))

    print("R",R)
    return R,V10,V20,D,Rmse

if __name__ == '__main__':
    print("=============start-------------")
    #存放所有的参数 最后一个为第一个列表的长度(分割时用)
    list_str = []
    #存放字符型list
    list1_str=[]
    list2_str=[]
    #字符型转换为int型
    list_int=[]
    list1_int=[]
    list2_int=[]

    print("len(sys.argv[1:])==",len(sys.argv[1:]))
    print("sys.argv[1:]==",sys.argv[1:])

    for i in range(1, len(sys.argv)):
        list_str.append(sys.argv[i].replace(",", ""))
    print("list_str[0]==",list_str[0])
    print("len(list_str)==",len(list_str))
    #处理第一个还有最后一个元素的格式
    list_str[0] = list_str[0].replace("[", "")
    list_str[len(sys.argv)-2] = list_str[len(sys.argv)-2].replace("]", "")

    print("=before===String-list===list_str",list_str)
    #取出最后一个数作为第一个列表的长度来分割列表
    list1Size=int(list_str[len(list_str)-1])
    print("list1Size==",list1Size)
    #根据size取出第一个列表list[a:b]表示取出下表为a到下标为b-1的值组成一个list
    list1_str=list_str[0:list1Size]
    print("list1_str==",list1_str)
    #取出第二个列表
    list2_str=list_str[list1Size:len(list_str)-1]
    print("list2_str==",list2_str)
    #将str转换为int
    list_int=list(map(int, list_str))
    list1_int=list(map(int, list1_str))
    list2_int=list(map(int, list2_str))
    print("list_int==",list_int)
    print("list1_int==",list1_int)
    print("list2_int==",list2_int)
    print(MetricsValue(list1_int,list2_int))
    print("-------------end===============")

 最终控制台打印结果:

list1-size()4
=============start-------------
len(sys.argv[1:])== 9
sys.argv[1:]== ['[3340,', '4525,', '7304,', '3335,', '5319,', '5319,', '3932,', '3932,', '4]']
list_str[0]== [3340
len(list_str)== 9
=before===String-list===list_str ['3340', '4525', '7304', '3335', '5319', '5319', '3932', '3932', '4']
list1Size== 4
list1_str== ['3340', '4525', '7304', '3335']
list2_str== ['5319', '5319', '3932', '3932']
list_int== [3340, 4525, 7304, 3335, 5319, 5319, 3932, 3932, 4]
list1_int== [3340, 4525, 7304, 3335]
list2_int== [5319, 5319, 3932, 3932]
R -0.4279893568893351
(-0.4279893568893351, 0.0, 0.25, -0.5495247640483161, 2017.0318539874377)
-------------end===============
----状态码0----运行成功

5、调用脚本,使用三方库,传递参数list,脚本接收二维数组

这一种跟上一步的过程类似,不同点就是脚本需要的参数是二维数组,直接上代码

 

/**
     * 接收二维数组
     *
     */
    @Test
    public void test7_ThirdPackage_param()  {
        String pythonPath="D:\\Program Files\\Python\\Python36\\python.exe ";
        String filePath="E:\\mlthfs\\src\\main\\resources\\pythonDemo\\test8.py ";

        Integer x_count=null;//因子个数
        Integer year_count=null;//年数

        List newList=new ArrayList<>();
        List list1=new ArrayList<>();
        list1.add(328);
        list1.add(941);
        list1.add(385);
        list1.add(4327);
        x_count=list1.size();
        year_count=4;//假设为4年
        List list2 = new ArrayList<>();
        //给list2赋值
        list2.add(388);
        list2.add(1529);
        list2.add(2063);
        list2.add(4108);

        List list3 = new ArrayList<>();
        list3.add(436);
        list3.add(891);
        list3.add(1719);
        list3.add(4272);

        List list4 = new ArrayList<>();
        list4.add(467);
        list4.add(2450);
        list4.add(1148);
        list4.add(1382);

        List list5 = new ArrayList<>();
        list4.add(3340);
        list4.add(4525);
        list4.add(7304);
        list4.add(3335);

        System.out.println("newList0"+newList);
        newList.addAll(list1);

        System.out.println("newList1"+newList);
        newList.addAll(list2);

        System.out.println("newList2"+newList);

        newList.addAll(list3);
        newList.addAll(list4);

        System.out.println("newList4"+newList);

        newList.addAll(list5);
        newList.add(x_count);
        newList.add(year_count);
        System.out.println(newList);
        try {

            Process process = Runtime.getRuntime().exec(
                    pythonPath + filePath +newList);
            BufferedReader in=new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line=in.readLine())!=null){
                System.out.println(line);
            }
            in.close();
            int re=process.waitFor();
            System.out.println(re==1?"----状态码1----运行失败":"----状态码0----运行成功");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

py脚本:

# -*- coding:utf-8 -*-
import sys
import numpy as np


# 评估指标
def MetricsValue(yobs,yfit):
    import numpy as np
    yyobs=np.array(yobs)
    yyfit=np.array(yfit)
    data =[yyobs, yyfit]
    R=np.corrcoef(data) [0,1]              # 相关系数

    # 预报的变幅误差
    yo_yp=yyfit-yyobs
    BFWC=yo_yp/np.ptp(yyobs)
    V10 = np.size(np.where((abs(BFWC) <= 0.1)))/np.size(yyobs)  # 非常要注意这个括号 没有括号估计内部执行顺序不对
    V20 = np.size(np.where((abs(BFWC) <=0.2))) / np.size(yyobs)

    # 确定性系数
    D1=np.sum(yo_yp**2)
    D2=np.sum((yyobs-np.mean(yyobs))**2)
    D=1-D1/D2

    #均方根误差RMSe
    Rmse1=sum(yo_yp**2)
    Rmse=np.sqrt(Rmse1/np.size(yyobs))

    print("R",R)
    return R,V10,V20,D,Rmse

# 拟合
def SVRFit (Obsx,Obsy):
    from sklearn.svm import SVR
    import numpy as np
    from sklearn.model_selection import cross_val_predict
    print("obsx",Obsx)
    print("obsy",Obsy)
    xobs=np.array(Obsx)
    yobs=np.array(Obsy)
    modelFit=SVR(kernel='rbf', C=1e3, gamma=0.1)
    yfit = cross_val_predict(modelFit, xobs, yobs, cv=2)# 交叉验证返回对应的拟合值,根据Obsy和yfit计算评估指标
    MetrValue=MetricsValue(yobs,yfit)
    modelFit.fit(xobs,yobs)
    print('MetrValue', MetrValue)
    print('yfit', yfit)
    return MetrValue, yfit


if __name__ == '__main__':

    print("=============start-------------")
    # 存放所有的参数 最后一个为第一个列表的长度(分割时用)
    list_str = []
    # 存放字符型list
    list1_str = []
    list2_str = []
    # 字符型转换为int型
    list_int = []
    list1_int = []
    list2_int = []
    # 存放转换出来的二维数组
    list1_int2 = []

    print("len(sys.argv[1:])==", len(sys.argv[1:]))
    print("sys.argv[1:]==", sys.argv[1:])

    for i in range(1, len(sys.argv)):
        list_str.append(sys.argv[i].replace(",", ""))
    print("list_str[0]==", list_str[0])
    print("len(list_str)==", len(list_str))
    # 处理第一个还有最后一个元素的格式
    list_str[0] = list_str[0].replace("[", "")
    list_str[len(sys.argv) - 2] = list_str[len(sys.argv) - 2].replace("]", "")
    print("=before===String-list===list_str", list_str)
    # 年数(行数)
    year_count = int(list_str[len(list_str) - 1])
    # 因子个数(列数)
    x_count = int(list_str[len(list_str) - 2])
    print("year_count=行数=", year_count)
    print("x_count=列数=", x_count)
    # 第一个数组
    list1_str = list_str[0:int(year_count * x_count)]
    print("list1", list1_str)
    list1_int = list(map(int, list1_str))
    print("list1_int", list1_int)
    # 使用numpy库的函数将一维数组转换为二维
    list1_int2 = np.array(list1_int).reshape((year_count, x_count))
    print("list1_int2", list1_int2)
    # 第二个数组
    list2_str = list_str[int(year_count * x_count):len(list_str) - 2]
    print("list2_str", list2_str)
    list2_int = list(map(int, list2_str))
    print("list2_int", list2_int)
    print("-------------result:===============")
    print("list1_int2", list1_int2)
    print("list2_int", list2_int)

    print(SVRFit(list1_int2,list2_int))
    print("-------------end===============")

运行结果:

=============start-------------
len(sys.argv[1:])== 22
sys.argv[1:]== ['[328,', '941,', '385,', '4327,', '388,', '1529,', '2063,', '4108,', '436,', '891,', '1719,', '4272,', '467,', '2450,', '1148,', '1382,', '3340,', '4525,', '7304,', '3335,', '4,', '4]']
list_str[0]== [328
len(list_str)== 22
=before===String-list===list_str ['328', '941', '385', '4327', '388', '1529', '2063', '4108', '436', '891', '1719', '4272', '467', '2450', '1148', '1382', '3340', '4525', '7304', '3335', '4', '4']
year_count=����= 4
x_count=����= 4
list1 ['328', '941', '385', '4327', '388', '1529', '2063', '4108', '436', '891', '1719', '4272', '467', '2450', '1148', '1382']
list1_int [328, 941, 385, 4327, 388, 1529, 2063, 4108, 436, 891, 1719, 4272, 467, 2450, 1148, 1382]
list1_int2 [[ 328  941  385 4327]
 [ 388 1529 2063 4108]
 [ 436  891 1719 4272]
 [ 467 2450 1148 1382]]
list2_str ['3340', '4525', '7304', '3335']
list2_int [3340, 4525, 7304, 3335]
-------------result:===============
list1_int2 [[ 328  941  385 4327]
 [ 388 1529 2063 4108]
 [ 436  891 1719 4272]
 [ 467 2450 1148 1382]]
list2_int [3340, 4525, 7304, 3335]
obsx [[ 328  941  385 4327]
 [ 388 1529 2063 4108]
 [ 436  891 1719 4272]
 [ 467 2450 1148 1382]]
obsy [3340, 4525, 7304, 3335]
R -0.4279893568893351
MetrValue (-0.4279893568893351, 0.0, 0.25, -0.54952466883164, 2017.0317920151879)
yfit [5319.5 5319.5 3932.5 3932.5]
((-0.4279893568893351, 0.0, 0.25, -0.54952466883164, 2017.0317920151879), array([5319.5, 5319.5, 3932.5, 3932.5]))
-------------end===============
----状态码0----运行成功

 

你可能感兴趣的:(java 调用 python脚本并传递参数list)