14

Java、Python、C混合编程

 3 years ago
source link: https://www.guofei.site/2021/09/12/hybrid.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Java、Python、C混合编程

2021年09月12日    Author:Guofei

文章归类: 语言    文章编号: 173


版权声明:本文作者是郭飞。转载随意,但需要标明原文链接,并通知本人
原文链接:https://www.guofei.site/2021/09/12/hybrid.html

Edit

【ctypes】python 调 C

  • 优点:无需处理 Python 版本
  • 缺点:不能多线程
  1. 写 c 文件, 保存为 file.c
    #include<stdio.h>
    void add()
    {
    int sum=0;
    for(int i=0;i<1000;i++)
    sum+=i;
    printf("sum:%d\n",sum);
    }
    
  2. file.c 文件编译为 file.sogcc file.c -shared -o file.so
  3. 在Python中导入和使用 .so
    from ctypes import *
    clib = cdll.LoadLibrary("./file.so")
    clib.add()
    

如何同时支持 windows/Linux : https://www.bilibili.com/video/BV17y4y1W7BY?p=3

数据类型

ctypes 类型 C 类型 Python 数据类型 c_bool _Bool bool (1) c_char char 单字符字节串对象 c_wchar wchar_t 单字符字符串 c_byte char int c_ubyte unsigned char int c_short short int c_ushort unsigned short int c_int int int c_uint unsigned int int c_long long int c_ulong unsigned long int c_longlong __int64 或 long long int c_ulonglong unsigned __int64 或 unsigned long long int c_size_t size_t int c_ssize_t ssize_t 或 Py_ssize_t int c_float float float c_double double float c_longdouble long double float c_char_p char * (NUL terminated) 字节串对象或 None c_wchar_p wchar_t * (NUL terminated) 字符串或 None c_void_p void * int 或 None

  1. C程序
    #include<stdio.h>
    void MyTst(int x, float y)
    {
      printf("%d,%f\n", x, y);
    }
    
  2. Python
    import ctypes
    clib = ctypes.cdll.LoadLibrary("./file.so")
    # 整形无须转化,但浮点型必须转化
    clib.MyTst(1, ctypes.c_float(2.000))
    

【JPype1】Python 调 Java

pip install JPype1

示例java脚本

package com.guofei9987.learn_java;

public class JavaClass {

    public static String tstStatic(String a) {
        return "调用了静态方法,入参:" + a;
    }

    public int tstInt(int a, int b) {
        return a + b + 2;
    }

    public String tstStr(String a) {
        return "调用了方法,入参:" + a;
    }

    public String tstStr(int a) {
        return "调用了重载的方法,入参:" + a;
    }
}

Python 调用 Java

import jpype
import os

jarpath = os.path.join(os.path.abspath("."), "/Users/guofei/git/learn/learn_java/target/learn_java-1.0-SNAPSHOT.jar")
jvmPath = jpype.getDefaultJVMPath()
jpype.startJVM(jvmPath, "-ea", "-Djava.class.path=%s" % (jarpath))

# step1:加载类
javaClass = jpype.JClass("com.guofei9987.learn_java.JavaClass")

# step2:实例化java对象
javaInstance = javaClass()

# step3:调用java方法
javaClass.tstStatic("Hello")
# >>>'调用了静态方法,入参:Hello'

javaInstance.tstInt(1, 2)
# >>> 5

javaInstance.tstStr("Hello")
# >>>'调用了方法,入参:Hello'

javaInstance.tstStr(3)
# >>>'调用了重载的方法,入参:3'

# ④、关闭jvm
jpype.shutdownJVM()

【PMML】Java调 sklearn 算法模型

描述

Python 训练算法模型,保存为 PMML 文件。然后 Java 调用 PMML 文件做预测,这样线上就变成纯 JAVA 项目了。

  • Python 端的项目:https://github.com/jpmml/sklearn2pmml
  • Java端 项目:https://github.com/jpmml/jpmml-model
  • 对应的库:https://repo1.maven.org/maven2/org/jpmml/
  • Python
    pip install scikit-learn==0.24.2
    pip install sklearn2pmml==0.74.4
  • JAVA ```xml

org.jpmml pmml-evaluator 1.5.9








### 使用



python 训练模型
```python
from sklearn import tree
from sklearn.datasets import load_iris
from sklearn2pmml.pipeline import PMMLPipeline
from sklearn2pmml import sklearn2pmml

iris = load_iris()
X, y = iris.data, iris.target
pipeline = PMMLPipeline([("classifier", tree.DecisionTreeClassifier())])  # 用决策树分类
pipeline.fit(X, y)
sklearn2pmml(pipeline, "iris.pmml", with_repr=True)

java 调用模型做预测

package com.alipay.tianqian;

import org.dmg.pmml.FieldName;
import org.jpmml.evaluator.*;
import org.xml.sax.SAXException;

import javax.xml.bind.JAXBException;
import java.io.*;
import java.util.*;


public class TestPmml {

    public static void main(String[] args) throws JAXBException, SAXException, IOException {
        TestPmml obj = new TestPmml();

        Evaluator model = new LoadingModelEvaluatorBuilder()
                .load(new File("src/iris.pmml"))
                .build();

        List<Map<String, Object>> inputs = new ArrayList<>();
        inputs.add(obj.getRawMap(5.1, 3.5, 1.4, 0.2));
        inputs.add(obj.getRawMap(4.9, 3, 1.5, 4));
        for (Map<String, Object> input : inputs) {
            Map<String, Object> output = obj.predict(model, input);
            System.out.println("X=" + input + " -> y=" + output.get("y"));
        }
    }



    private Map<String, Object> getRawMap(Object a, Object b, Object c, Object d) {
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("x1", a);
        data.put("x2", b);
        data.put("x3", c);
        data.put("x4", d);
        return data;
    }

    /**
     * 运行模型得到结果。
     */
    private Map<String, Object> predict(Evaluator evaluator, Map<String, Object> data) {
        Map<FieldName, FieldValue> input = getFieldMap(evaluator, data);
        Map<String, Object> output = evaluate(evaluator, input);
        return output;
    }

    /**
     * 把原始输入转换成PMML格式的输入。
     */
    private Map<FieldName, FieldValue> getFieldMap(Evaluator evaluator, Map<String, Object> input) {
        List<InputField> inputFields = evaluator.getInputFields();
        Map<FieldName, FieldValue> map = new LinkedHashMap<FieldName, FieldValue>();
        for (InputField field : inputFields) {
            FieldName fieldName = field.getName();
            Object rawValue = input.get(fieldName.getValue());
            FieldValue value = field.prepare(rawValue);
            map.put(fieldName, value);
        }
        return map;
    }

    /**
     * 运行模型得到结果。
     */
    private Map<String, Object> evaluate(Evaluator evaluator, Map<FieldName, FieldValue> input) {
        Map<FieldName, ?> results = evaluator.evaluate(input);
        List<TargetField> targetFields = evaluator.getTargetFields();
        Map<String, Object> output = new LinkedHashMap<String, Object>();
        for (TargetField field : targetFields) {
            FieldName fieldName = field.getName();
            Object value = results.get(fieldName);
            if (value instanceof Computable) {
                Computable computable = (Computable) value;
                value = computable.getResult();
            }
            output.put(fieldName.getValue(), value);
        }
        return output;
    }
}

旧版本

  • PMML 文件:4.3版本
  • python 版本
    pip install sklearn2pmml==0.56.2
    pip install scikit-learn==0.22.2
  • java 版本: ```xml

org.jpmml pmml-evaluator 1.4.1

org.jpmml pmml-evaluator-extension 1.4.1




#### 旧版本的使用

Python 训练模型,步骤同上


Java调模型,做预测
```java
package com.alipay.tianqian.service;

import org.dmg.pmml.FieldName;
import org.dmg.pmml.PMML;
import org.jpmml.evaluator.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;

import javax.xml.bind.JAXBException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;


public class TestPmml2 {
    public static void main(String args[]) throws FileNotFoundException, JAXBException, SAXException {
        String fp = "src/iris.pmml";
        TestPmml2 obj = new TestPmml2();
        Evaluator model = obj.loadPmml(fp);
        List<Map<String, Object>> inputs = new ArrayList<>();
        inputs.add(obj.getRawMap(5.1, 3.5, 1.4, 0.2));
        inputs.add(obj.getRawMap(4.9, 3, 1.5, 0.9));
        for (int i = 0; i < inputs.size(); i++) {
            Map<String, Object> output = obj.predict(model, inputs.get(i));
            System.out.println("X=" + inputs.get(i) + " -> y=" + output.get("y"));
        }
    }

    private Evaluator loadPmml(String fp) throws FileNotFoundException, JAXBException, SAXException {
        InputStream is = new FileInputStream(fp);
        PMML pmml = org.jpmml.model.PMMLUtil.unmarshal(is);
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        ModelEvaluatorFactory factory = ModelEvaluatorFactory.newInstance();
        return factory.newModelEvaluator(pmml);
    }

    private Map<String, Object> getRawMap(Object a, Object b, Object c, Object d) {
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("x1", a);
        data.put("x2", b);
        data.put("x3", c);
        data.put("x4", d);
        return data;
    }

    /**
     * 运行模型得到结果。
     */
    private Map<String, Object> predict(Evaluator evaluator, Map<String, Object> data) {
        Map<FieldName, FieldValue> input = getFieldMap(evaluator, data);
        Map<String, Object> output = evaluate(evaluator, input);
        return output;
    }

    /**
     * 把原始输入转换成PMML格式的输入。
     */
    private Map<FieldName, FieldValue> getFieldMap(Evaluator evaluator, Map<String, Object> input) {
        List<InputField> inputFields = evaluator.getInputFields();
        Map<FieldName, FieldValue> map = new LinkedHashMap<FieldName, FieldValue>();
        for (InputField field : inputFields) {
            FieldName fieldName = field.getName();
            Object rawValue = input.get(fieldName.getValue());
            FieldValue value = field.prepare(rawValue);
            map.put(fieldName, value);
        }
        return map;
    }

    /**
     * 运行模型得到结果。
     */
    private Map<String, Object> evaluate(Evaluator evaluator, Map<FieldName, FieldValue> input) {
        Map<FieldName, ?> results = evaluator.evaluate(input);
        List<TargetField> targetFields = evaluator.getTargetFields();
        Map<String, Object> output = new LinkedHashMap<String, Object>();
        for (int i = 0; i < targetFields.size(); i++) {
            TargetField field = targetFields.get(i);
            FieldName fieldName = field.getName();
            Object value = results.get(fieldName);
            if (value instanceof Computable) {
                Computable computable = (Computable) value;
                value = computable.getResult();
            }
            output.put(fieldName.getValue(), value);
        }
        return output;
    }
}

您的支持将鼓励我继续创作!


Recommend

  • 174
    • 掘金 juejin.im 7 years ago
    • Cache

    Android混合编程:WebView实践

    关于作者 郭孝星,程序员,吉他手,主要从事Android平台基础架构方面的工作,欢迎交流技术方面的问题,可以去我的

  • 91

  • 45
    • www.tuicool.com 5 years ago
    • Cache

    浅谈C/C++混合编程

    ****如只想知道怎样就能实现C/C++混合编程而不深究为什么的话, 可以一拉到底直接看总结.**** 首先, 在介绍C/C++混合编程之前, 先思考几个问题 1. C/C++混合编程是什么? 2. C/C++混合编程有什么用? 3....

  • 69
    • yulingtianxia.com 5 years ago
    • Cache

    谈谈 dart_objc 混合编程引擎的设计

    我之前在 『 用 Dart 来写 Objective-C 代码 』 这篇文章讲了下我在解决 Flutter 三端开发问题的一个思路和方案,并给出了 Demo 和简单的对...

  • 34

    1-1 Go+Python双语言混合开发-课程导学 (11:35)

  • 3
    • www.viseator.com 4 years ago
    • Cache

    80x86下汇编与C语言的混合编程

    在汇编课程中的实验中要求了我们在80x86下实现C语言与汇编代码的混合编程,虽然80x86时代离现代有些久远,但我们仍可以把80x86当作x86的一个简化版本来学习一些重要的概念。 从一个例子开始

  • 9
    • blogread.cn 3 years ago
    • Cache

    C#和C++混合编程的一些tips

    C#和C++混合编程的一些tips 浏览:2959次  出处信息 最近帮朋友写个小东西的时候,刚好用到了C#和C++的混合编程,记...

  • 5

    我们都知道前端开发中论开发效率,用类似小程序的开发效率要高于Android和IOS,因为小程序采用了H5的设计思想,采用Html5标签、CSS做页面布局和样式,JS控制逻辑和交互,H5的编写页面效率要远远高于Android和IOS,因此现代很多APP都采用了WebView方式的混合开发...

  • 25
    • www.guofei.site 3 years ago
    • Cache

    【Python-c】Python 与 C 混合编程

    【Python-c】Python 与 C 混合编程 2021年11月06日    Author:Guofei 文章归类: 1-1-算法平台    文章编号: 173 ...

  • 4
    • www.cnblogs.com 1 year ago
    • Cache

    混合编程python与C++ - Rurouni

    上个版本: 只是用到ctypes进行传输, 这次将python服务端更改为C++服务端,方便后续维护. 本文实现功能: python传输图片给C++, C++接受图片后对图片进行处理,并将...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK