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

╰半夏微凉° 2022-05-15 10:52 924阅读 0赞

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

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

  1. <!--jython-->
  2. <!-- https://mvnrepository.com/artifact/org.python/jython-standalone -->
  3. <dependency>
  4. <groupId>org.python</groupId>
  5. <artifactId>jython-standalone</artifactId>
  6. <version>2.7.1</version>
  7. </dependency>
  8. /**
  9. * 执行单行代码
  10. */
  11. @Test
  12. public void test1_code(){
  13. PythonInterpreter pythonInterpreter=new PythonInterpreter();
  14. pythonInterpreter.exec("print('-----执行单行代码:Hello')");
  15. }

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

hello.py:

  1. def hello():
  2. return '----py文件执行结果:Hello'
  3. /**
  4. * 执行文件脚本,有函数名不带参数,不使用三方库
  5. */
  6. @Test
  7. public void test2_file(){
  8. PythonInterpreter pythonInterpreter=new PythonInterpreter();
  9. //注意这边要用绝对路径
  10. pythonInterpreter.execfile("E:\\mlthfs\\src\\main\\resources\\pythonDemo\\hello.py");
  11. //第一个参数为期望获得的函数(变量)的名字,第二个参数为期望返回的对象类型
  12. PyFunction pyFunction=pythonInterpreter.get("hello",PyFunction.class);
  13. //调用函数,此时call无参数
  14. PyObject pyObject=pyFunction.__call__();
  15. System.out.println(pyObject);
  16. }

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

testWithParam.py:

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

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

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

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

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

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

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

  1. Process process = Runtime.getRuntime().exec(
  2. pythonPath + filePath + list1);
  3. public void test6_ThirdPackage_param() {
  4. String pythonPath="D:\\Program Files\\Python\\Python36\\python.exe ";
  5. String filePath="E:\\mlthfs\\src\\main\\resources\\pythonDemo\\test7.py ";
  6. //首先定义两个list,赋值。
  7. List<Integer> list1 = new ArrayList<>();
  8. List<Integer> list2 = new ArrayList<>();
  9. Integer list1Size=null;
  10. //给list1赋值
  11. list1.add(3340);
  12. list1.add(4525);
  13. list1.add(7304);
  14. list1.add(3335);
  15. //给list2赋值
  16. list2.add(5319);
  17. list2.add(5319);
  18. list2.add(3932);
  19. list2.add(3932);
  20. //得到第一个list的size,传入脚本中,方便分割参数
  21. list1Size=list1.size();
  22. System.out.println("list1-size()"+list1.size());
  23. //将list1.list2合并
  24. list1.addAll(list2);
  25. //将size加到list1最后
  26. list1.add(list1Size);
  27. try {
  28. Process process = Runtime.getRuntime().exec(
  29. pythonPath + filePath + list1);
  30. BufferedReader in=new BufferedReader(new InputStreamReader(process.getInputStream()));
  31. String line;
  32. while ((line=in.readLine())!=null){
  33. System.out.println(line);
  34. }
  35. in.close();
  36. int re=process.waitFor();
  37. System.out.println(re==1?"----状态码1----运行失败":"----状态码0----运行成功");
  38. } catch (IOException e) {
  39. e.printStackTrace();
  40. } catch (InterruptedException e) {
  41. e.printStackTrace();
  42. }
  43. }

py脚本:

  1. import sys
  2. # 评估指标
  3. def MetricsValue(yobs,yfit):
  4. import numpy as np
  5. yyobs=np.array(yobs)
  6. yyfit=np.array(yfit)
  7. data =[yyobs, yyfit]
  8. R=np.corrcoef(data) [0,1] # 相关系数
  9. # 预报的变幅误差
  10. yo_yp=yyfit-yyobs
  11. BFWC=yo_yp/np.ptp(yyobs)
  12. V10 = np.size(np.where((abs(BFWC) <= 0.1)))/np.size(yyobs) # 非常要注意这个括号 没有括号估计内部执行顺序不对
  13. V20 = np.size(np.where((abs(BFWC) <=0.2))) / np.size(yyobs)
  14. # 确定性系数
  15. D1=np.sum(yo_yp**2)
  16. D2=np.sum((yyobs-np.mean(yyobs))**2)
  17. D=1-D1/D2
  18. #均方根误差RMSe
  19. Rmse1=sum(yo_yp**2)
  20. Rmse=np.sqrt(Rmse1/np.size(yyobs))
  21. print("R",R)
  22. return R,V10,V20,D,Rmse
  23. if __name__ == '__main__':
  24. print("=============start-------------")
  25. #存放所有的参数 最后一个为第一个列表的长度(分割时用)
  26. list_str = []
  27. #存放字符型list
  28. list1_str=[]
  29. list2_str=[]
  30. #字符型转换为int型
  31. list_int=[]
  32. list1_int=[]
  33. list2_int=[]
  34. print("len(sys.argv[1:])==",len(sys.argv[1:]))
  35. print("sys.argv[1:]==",sys.argv[1:])
  36. for i in range(1, len(sys.argv)):
  37. list_str.append(sys.argv[i].replace(",", ""))
  38. print("list_str[0]==",list_str[0])
  39. print("len(list_str)==",len(list_str))
  40. #处理第一个还有最后一个元素的格式
  41. list_str[0] = list_str[0].replace("[", "")
  42. list_str[len(sys.argv)-2] = list_str[len(sys.argv)-2].replace("]", "")
  43. print("=before===String-list===list_str",list_str)
  44. #取出最后一个数作为第一个列表的长度来分割列表
  45. list1Size=int(list_str[len(list_str)-1])
  46. print("list1Size==",list1Size)
  47. #根据size取出第一个列表list[a:b]表示取出下表为a到下标为b-1的值组成一个list
  48. list1_str=list_str[0:list1Size]
  49. print("list1_str==",list1_str)
  50. #取出第二个列表
  51. list2_str=list_str[list1Size:len(list_str)-1]
  52. print("list2_str==",list2_str)
  53. #将str转换为int
  54. list_int=list(map(int, list_str))
  55. list1_int=list(map(int, list1_str))
  56. list2_int=list(map(int, list2_str))
  57. print("list_int==",list_int)
  58. print("list1_int==",list1_int)
  59. print("list2_int==",list2_int)
  60. print(MetricsValue(list1_int,list2_int))
  61. print("-------------end===============")

最终控制台打印结果:

  1. list1-size()4
  2. =============start-------------
  3. len(sys.argv[1:])== 9
  4. sys.argv[1:]== ['[3340,', '4525,', '7304,', '3335,', '5319,', '5319,', '3932,', '3932,', '4]']
  5. list_str[0]== [3340
  6. len(list_str)== 9
  7. =before===String-list===list_str ['3340', '4525', '7304', '3335', '5319', '5319', '3932', '3932', '4']
  8. list1Size== 4
  9. list1_str== ['3340', '4525', '7304', '3335']
  10. list2_str== ['5319', '5319', '3932', '3932']
  11. list_int== [3340, 4525, 7304, 3335, 5319, 5319, 3932, 3932, 4]
  12. list1_int== [3340, 4525, 7304, 3335]
  13. list2_int== [5319, 5319, 3932, 3932]
  14. R -0.4279893568893351
  15. (-0.4279893568893351, 0.0, 0.25, -0.5495247640483161, 2017.0318539874377)
  16. -------------end===============
  17. ----状态码0----运行成功

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

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

  1. /**
  2. * 接收二维数组
  3. *
  4. */
  5. @Test
  6. public void test7_ThirdPackage_param() {
  7. String pythonPath="D:\\Program Files\\Python\\Python36\\python.exe ";
  8. String filePath="E:\\mlthfs\\src\\main\\resources\\pythonDemo\\test8.py ";
  9. Integer x_count=null;//因子个数
  10. Integer year_count=null;//年数
  11. List<Integer> newList=new ArrayList<>();
  12. List<Integer> list1=new ArrayList<>();
  13. list1.add(328);
  14. list1.add(941);
  15. list1.add(385);
  16. list1.add(4327);
  17. x_count=list1.size();
  18. year_count=4;//假设为4年
  19. List<Integer> list2 = new ArrayList<>();
  20. //给list2赋值
  21. list2.add(388);
  22. list2.add(1529);
  23. list2.add(2063);
  24. list2.add(4108);
  25. List<Integer> list3 = new ArrayList<>();
  26. list3.add(436);
  27. list3.add(891);
  28. list3.add(1719);
  29. list3.add(4272);
  30. List<Integer> list4 = new ArrayList<>();
  31. list4.add(467);
  32. list4.add(2450);
  33. list4.add(1148);
  34. list4.add(1382);
  35. List<Integer> list5 = new ArrayList<>();
  36. list4.add(3340);
  37. list4.add(4525);
  38. list4.add(7304);
  39. list4.add(3335);
  40. System.out.println("newList0"+newList);
  41. newList.addAll(list1);
  42. System.out.println("newList1"+newList);
  43. newList.addAll(list2);
  44. System.out.println("newList2"+newList);
  45. newList.addAll(list3);
  46. newList.addAll(list4);
  47. System.out.println("newList4"+newList);
  48. newList.addAll(list5);
  49. newList.add(x_count);
  50. newList.add(year_count);
  51. System.out.println(newList);
  52. try {
  53. Process process = Runtime.getRuntime().exec(
  54. pythonPath + filePath +newList);
  55. BufferedReader in=new BufferedReader(new InputStreamReader(process.getInputStream()));
  56. String line;
  57. while ((line=in.readLine())!=null){
  58. System.out.println(line);
  59. }
  60. in.close();
  61. int re=process.waitFor();
  62. System.out.println(re==1?"----状态码1----运行失败":"----状态码0----运行成功");
  63. } catch (IOException e) {
  64. e.printStackTrace();
  65. } catch (InterruptedException e) {
  66. e.printStackTrace();
  67. }
  68. }

py脚本:

  1. # -*- coding:utf-8 -*-
  2. import sys
  3. import numpy as np
  4. # 评估指标
  5. def MetricsValue(yobs,yfit):
  6. import numpy as np
  7. yyobs=np.array(yobs)
  8. yyfit=np.array(yfit)
  9. data =[yyobs, yyfit]
  10. R=np.corrcoef(data) [0,1] # 相关系数
  11. # 预报的变幅误差
  12. yo_yp=yyfit-yyobs
  13. BFWC=yo_yp/np.ptp(yyobs)
  14. V10 = np.size(np.where((abs(BFWC) <= 0.1)))/np.size(yyobs) # 非常要注意这个括号 没有括号估计内部执行顺序不对
  15. V20 = np.size(np.where((abs(BFWC) <=0.2))) / np.size(yyobs)
  16. # 确定性系数
  17. D1=np.sum(yo_yp**2)
  18. D2=np.sum((yyobs-np.mean(yyobs))**2)
  19. D=1-D1/D2
  20. #均方根误差RMSe
  21. Rmse1=sum(yo_yp**2)
  22. Rmse=np.sqrt(Rmse1/np.size(yyobs))
  23. print("R",R)
  24. return R,V10,V20,D,Rmse
  25. # 拟合
  26. def SVRFit (Obsx,Obsy):
  27. from sklearn.svm import SVR
  28. import numpy as np
  29. from sklearn.model_selection import cross_val_predict
  30. print("obsx",Obsx)
  31. print("obsy",Obsy)
  32. xobs=np.array(Obsx)
  33. yobs=np.array(Obsy)
  34. modelFit=SVR(kernel='rbf', C=1e3, gamma=0.1)
  35. yfit = cross_val_predict(modelFit, xobs, yobs, cv=2)# 交叉验证返回对应的拟合值,根据Obsyyfit计算评估指标
  36. MetrValue=MetricsValue(yobs,yfit)
  37. modelFit.fit(xobs,yobs)
  38. print('MetrValue', MetrValue)
  39. print('yfit', yfit)
  40. return MetrValue, yfit
  41. if __name__ == '__main__':
  42. print("=============start-------------")
  43. # 存放所有的参数 最后一个为第一个列表的长度(分割时用)
  44. list_str = []
  45. # 存放字符型list
  46. list1_str = []
  47. list2_str = []
  48. # 字符型转换为int型
  49. list_int = []
  50. list1_int = []
  51. list2_int = []
  52. # 存放转换出来的二维数组
  53. list1_int2 = []
  54. print("len(sys.argv[1:])==", len(sys.argv[1:]))
  55. print("sys.argv[1:]==", sys.argv[1:])
  56. for i in range(1, len(sys.argv)):
  57. list_str.append(sys.argv[i].replace(",", ""))
  58. print("list_str[0]==", list_str[0])
  59. print("len(list_str)==", len(list_str))
  60. # 处理第一个还有最后一个元素的格式
  61. list_str[0] = list_str[0].replace("[", "")
  62. list_str[len(sys.argv) - 2] = list_str[len(sys.argv) - 2].replace("]", "")
  63. print("=before===String-list===list_str", list_str)
  64. # 年数(行数)
  65. year_count = int(list_str[len(list_str) - 1])
  66. # 因子个数(列数)
  67. x_count = int(list_str[len(list_str) - 2])
  68. print("year_count=行数=", year_count)
  69. print("x_count=列数=", x_count)
  70. # 第一个数组
  71. list1_str = list_str[0:int(year_count * x_count)]
  72. print("list1", list1_str)
  73. list1_int = list(map(int, list1_str))
  74. print("list1_int", list1_int)
  75. # 使用numpy库的函数将一维数组转换为二维
  76. list1_int2 = np.array(list1_int).reshape((year_count, x_count))
  77. print("list1_int2", list1_int2)
  78. # 第二个数组
  79. list2_str = list_str[int(year_count * x_count):len(list_str) - 2]
  80. print("list2_str", list2_str)
  81. list2_int = list(map(int, list2_str))
  82. print("list2_int", list2_int)
  83. print("-------------result:===============")
  84. print("list1_int2", list1_int2)
  85. print("list2_int", list2_int)
  86. print(SVRFit(list1_int2,list2_int))
  87. print("-------------end===============")

运行结果:

  1. =============start-------------
  2. len(sys.argv[1:])== 22
  3. 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]']
  4. list_str[0]== [328
  5. len(list_str)== 22
  6. =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']
  7. year_count=����= 4
  8. x_count=����= 4
  9. list1 ['328', '941', '385', '4327', '388', '1529', '2063', '4108', '436', '891', '1719', '4272', '467', '2450', '1148', '1382']
  10. list1_int [328, 941, 385, 4327, 388, 1529, 2063, 4108, 436, 891, 1719, 4272, 467, 2450, 1148, 1382]
  11. list1_int2 [[ 328 941 385 4327]
  12. [ 388 1529 2063 4108]
  13. [ 436 891 1719 4272]
  14. [ 467 2450 1148 1382]]
  15. list2_str ['3340', '4525', '7304', '3335']
  16. list2_int [3340, 4525, 7304, 3335]
  17. -------------result:===============
  18. list1_int2 [[ 328 941 385 4327]
  19. [ 388 1529 2063 4108]
  20. [ 436 891 1719 4272]
  21. [ 467 2450 1148 1382]]
  22. list2_int [3340, 4525, 7304, 3335]
  23. obsx [[ 328 941 385 4327]
  24. [ 388 1529 2063 4108]
  25. [ 436 891 1719 4272]
  26. [ 467 2450 1148 1382]]
  27. obsy [3340, 4525, 7304, 3335]
  28. R -0.4279893568893351
  29. MetrValue (-0.4279893568893351, 0.0, 0.25, -0.54952466883164, 2017.0317920151879)
  30. yfit [5319.5 5319.5 3932.5 3932.5]
  31. ((-0.4279893568893351, 0.0, 0.25, -0.54952466883164, 2017.0317920151879), array([5319.5, 5319.5, 3932.5, 3932.5]))
  32. -------------end===============
  33. ----状态码0----运行成功

发表评论

表情:
评论列表 (有 0 条评论,924人围观)

还没有评论,来说两句吧...

相关阅读