[Python] Java와 Python 연동

34. Java와 Python 연동

 

34.1 Java에서 Python 명령어를 실행하는 방법

34.1.1 Jython

Python 2.7 기준의 문법이 적용됨

numpy, pandas 등의 외부 라이브러리 사용이 어려운 단점이 있음

 

34.1.2 JEP

34.1.3 pyro4

34.1.4 Java에 내장된 Process 명령어를 사용하는 방법

 

 

34.2 Jython 설치

Jython 2.7.2 Installer 버전 다운로드 및 설치

다운로드받은 python-installer-2.7.2.jar 파일을 더블 클릭하여 기본 옵션으로 설치함(설치 디렉토리는 C:\jython2.7로 통일)

프로젝트 경로에 한글이 포함되어 있으면 아래와 같은 에러가 발생함

Cannot create PyString with non-byte value

 

libs 디렉토리를 만들지 말고 외부 jar로 C:\jython2.7\jython.jar를 추가해야 함

 

자바 프로젝트에서 Preferences(Alt + Enter) 를 통해 jar 파일 추가

 

 

34.3 실습예제

이클립스의 [Preferences] - [PyDev] - [Interpreters] - [Jython Interpreter] 메뉴에서 jython 2.7.2 경로 지정

jython 2.7은 파이썬 2.7 문법을 따른다.

 

 

Jython에서 UTF-8 인코딩을 인식하도록 하기 위해서 아래와 같이 설정

[Run Configurations] - [VM arguments] 입력란에 아래 내용 입력

- Dpython.console.encoding=UTF-8

 

34.3.1 Ex01.java

import org.python.core.PyObject;
import org.python.util.PythonInterpreter;

public class Ex01 {
    public static void main(String[] args) {
        // 파이썬 인터프리터 객체
        PythonInterpreter python = new PythonInterpreter();

        // num 변수에 20 할당
        python.set("num", 20);

        // 파이썬 코드 실행
        python.exec("square = a * a");

        // 파이썬 변수를 자바 변수로 변환
        PyInteger square = (PyInteger) python.get("square");

        // 파이썬 객체를 숫자로 변환
        System.out.println("square: " + square.asInt());

        // 파이썬 인터프리터 닫기
        python.close();
    }
}

 

34.3.2 Ex02.java

import org.python.core.PyObject;
import org.python.util.PythonInterpreter;

public class Ex02 {
    public static void main(String[] args) {
        PythonInterpreter python = new PythonInterpreter();

        // 모듈 로딩
        python.exec("import sys");
        python.exec("print(sys)");

        // 파이썬 변수에 값을 대입
        // python.set("num", 100);
        // python.exec("num = " + 100);

        int num = 100;
        python.exec("num = " + num);
        python.exec("print(num)");
        python.exec("x = 3 + 3");

        // 파이썬 변수를 자바로 가져옴
        PyObject po = python.get("x");
        System.out.println("po: " + x);

        python.close();
    }
}

 

34.3.3 Ex03_list.java

import org.python.core.PyList;
import org.python.util.PythonInterpreter;

public class Ex03_list {
    public static void main(String[] args) {
        PythonInterpreter python = new PythonInterpreter();

        python.exec("numbers = list(range(1, 6))");
        PyList pl = (PyList) python.get("numbers");
        System.out.println("list: ", pl);
        System.out.println("size: ", pl.size());

        for (int i = 0; i < pl.size(); i++) {
            System.out.println(pl.get(i));
        }

        python.close();
    }
}

 

34.3.4 gugu.py

# Python 2.7 syntax
print "result:"
for i in range(1, 10):
    print("{0} x {1} = {2:2d}".format(dan, i, dan * i))

 

34.3.5 Ex04_gugu.java

import java.io.StringWriter;

import org.python.util.PythonInterpreter;

public class Ex04_gugu {
    public static void main(String[] args) throws Exception {
        PythonInterpreter python = new PythonInterpreter();

        // 출력 방향을 자바 콘솔로 설정
        StringWriter out = new StringWriter();
        python.setOut(out);

        // 파이썬 스크립트 파일(gugu.py) 코드 내부 변수 dan에 값 전달
        python.set("dan", 7);
        python.execfile("D:/work/python/source/gugu.py");

        String result = out.toString();
        System.out.println(result);
        python.close();
    }
}

 

34.3.6 args.py

import sys
a = int(sys.argv[1])
b = int(sys.argv[2])
sum = a + b
print(sum)
python args.py 100 200

 

34.3.7 Ex05_args.java

import java.io.StringWriter;

import org.python.util.PythonInterpreter;

public class Ex05_args {
    public static void main(String[] args) throws Exception {
        String[] arguments = { "args.py", "100", "200" };
        PythonInterpreter.initialize(System.getProperties(), System.getProperties(), arguments);

    PythonInterpreter python = new PythonInterpreter();
        StringWriter out = new StringWriter();
        python.setOut(out);
        python.execfile("D:/work/python/source/args.py");
        
        String result = out.toString();
        System.out.println(result);
        python.close();
    }
}

 

34.3.8 gugu_args.py

import sys
dan = int(sys.argv[1])
for i in range(1, 10):
    print("{0} x {1} = {2:2d}".format(dan, i, dan * i))

 

34.3.9 Ex06_gugu_args.java

import java.io.StringWriter;

import org.python.util.PythonInterpreter;

public class Ex06_gugu_args {
    public static void main(String[] args) throws Exception {
        String[] arguments = { "gugu_args.py", "9" };
        PythonInterpreter.initialize(System.getProperties(), System.getProperties(), arguments);

    PythonInterpreter python = new PythonInterpreter();
        StringWriter out = new StringWriter();
        python.setOut(out);
        python.execfile("D:/work/python/source/gugu_args.py");

        String result = out.toString();
        System.out.println(result);
        python.close();
    }
}

 

34.3.10 Ex07_script.java

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

/**
 * ScriptEngine: python, javascript, ruby, grooby 등의 다양한 언어 호출 가능
 */
public class Ex07_script {
    public static void main(String[] args) throws Exception {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("python");
        try {
            engine.eval("print('Python - Hello world')");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

34.3.11 sum.py

a = 10
b = 20
print(a + b)

 

34.3.12 Ex08_script_sum.java

import java.io.FileReader;
import java.io.StringWriter;

import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.SimpleScriptContext;

public class Ex08_script_sum {
    public static void main(String[] args) throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptContext context = new SimpleScriptContext();

        // 출력 방향 설정
        StringWriter writer = new StringWriter();
        context.setWriter(writer);
        ScriptEngine engine = manager.getEngineByName("python");
        engine.eval(new FileReader("D:/work/python/source/sum.py"), context);
        System.out.println(writer.toString());
    }
}

 

34.3.13 Ex09_script_io

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class Ex09_script_io {
    public static void main(String[] args) throws Exception {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("python");
        engine.eval("import sys");
        engine.eval("print(sys)");
        engine.put("a", 153);
        engine.eval("print(a)");
        engine.eval("x = 3 + 4");
        Object x = engine.get("x");
        System.out.println("x: " + x);
    }
}

 

34.3.14 ozone.py

import pandas as pd
from scipy import stats

df = pd.read_csv("D:/data/ozone/ozone.csv")

print(df.head())

df2 = df.dropna(axis = 0)
print(df2.head())

x2 = df2["Temp"].values
y2 = df2["Ozone"].values

result = stats.linregress(x2, y2)
print(result)

slope, intercept, r_value, stderr = stats.linregress(x2, y2)

print(80 * slope + intecept)

 

34.3.15 Ex10_Ozone.java

import java.io.BufferedReader;
import java.io.InputStreamReader;

/**
 * Jython에서는 아직 numpy, pandas 등의 외부 라이브러리를 직접 호출할 수 없고
 * CPython 또는 JyNI 등의 툴을 이용해야 한다.
 * 
 * 따라서 데이터 분석 등의 경우와 같이 외부 라이브러리의 호출이 필요한 경우에는
 * Java에 내장된 Process 호출 기능을 사용한다.
 */
public class Ex10_Ozone {
    public static void main(String[] args) throws Exception {
        // 파이썬 소스 파일에 한글 주석이 있으면 실행이 안됨
        // 출력 결과에 한글이 있으면 깨짐
        ProcessBuilder pb = new ProcessBuilder("python", "D:/work/python/source/ozone.py");
        Process p = pb.start();
        BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream(), "utf-8"));

        try {
            String line = "";
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

 

34.3.16 iris.py

import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import numpy as numpy

import sys
a = sys.argv[1]
print(a)

iris = datasets.load_iris()
print("data size: {}".format(iris['data'].shape))

X = iris.data[:, [2, 3]]
Y = iris.target

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)

sc = StandardScaler()
sc.fit(X_train)

X_train_std = sc.transform(X_train)
X_test_std = sc.transform(X_test)

from sklearn.tree import DecisionTreeClassifier

iris_tree = DecisionTreeClassifier(criterion='entropy', max_depth=3, random_state=0)
iris_tree.fit(X_train, y_train)

print("training dataset: {:.3f}".format(iris_tree.score(X_train, y_train)))

 

 


 

관련 글 한 눈에 보기

'programming > python' 카테고리의 다른 글

[Python] Tensorflow 실습  (0) 2019.09.11
[Python] Tensorflow 기초  (0) 2019.09.10
[Python] Java와 Python 연동  (4) 2019.09.04
[Python] Clustering, KNN  (0) 2019.09.03
[Python] SVM(Support Vector Machines)  (0) 2019.07.03
[Python] 의사결정나무  (0) 2019.07.02

댓글(4)

  • 질문있습니다.
    2020.09.10 11:04

    안녕하세요 혹시 jython에서 pandas를 사용하려고 하는데 방법이 있을까요? 제가 서치해본 결과로는 사용할 수 없다고해서요ㅠ

    • 2020.09.10 13:58 신고

      안녕하세요 :)
      Jython은 릴리즈 2.7에서 더 추가 개발 진행이 안 되고 있는 거로 알아요 ㅠㅠ
      pandas 같은 모듈은 네이티브 기반이라 CPython 기능을 지원하는 다른 솔루션이 필요합니당

      34.1.2에서 언급한 JEP 또는 JyNI를 적용해보는 걸 추천해 드립니다!
      - https://github.com/ninia/jep
      - https://jyni.org/

    • 2020.09.10 18:11

      감사합니다^^

  • 질문있습니다.
    2020.09.10 18:06

    답글달아주신건가요? 비밀댓글이라 안보이네요 ㅠ

Designed by JB FACTORY