私は py4j を使用して、ユーザーフレンドリーではない Java ライブラリーを中心にユーザーフレンドリーな Python ライブラリーを構築してきました。ほとんどの場合、これは簡単で、py4j は優れたツールです。ただし、Python と Java の間で行列を送信するときに問題が発生しました。
具体的には、整数行列を引数として受け入れるJavaの静的関数があります。
public class MyClass {
// ...
public static MyObject create(int[][] matrix) {
// ...
}
}
次のように Py4j からこれを呼び出せるようにしたいと思います。
def create_java_object(numpy_matrix):
# <code here checks that numpy_matrix is a (3 x n) integer matrix>
# ...
return java_instance.jvm.my.namespace.MyClass.create(numpy_matrix)
これは機能しませんが、それほど驚くことではありません。また、numpy_matrix
代わりにプレーンな python リストのリストに変換された場合も機能しません。関数呼び出しの前に、Java 配列を作成してデータを転送することで解決できると思っていました。
def create_java_object(numpy_matrix):
# <code here checks that numpy_matrix is a (3 x n) integer matrix>
# ...
java_matrix = java_instance.new_array(java_instance.jvm.int, 3, n)
for i in range(numpy_matrix.shape[1]):
java_matrix[0][i] = int(numpy_matrix[0, i])
java_matrix[1][i] = int(numpy_matrix[1, i])
java_matrix[2][i] = int(numpy_matrix[2, i])
return java_instance.jvm.my.namespace.MyClass.create(java_matrix)
これで、このコードは正しく実行されます。ただし、実行には約2 分かかります。ちなみに、私が扱っている行列は (3 x ~300,000) 要素のオーダーです。
行列を変換するだけで信じられないほどの時間を必要としない、Py4jでこれを行う標準的な方法はありますか? 1、2 秒かかることは気にしませんが、これでは遅すぎます。Py4j がこの種の通信用にセットアップされていない場合、Python 用の Java 相互運用ライブラリはありますか?
注: Java ライブラリは、int[][]
行列を不変の配列として扱います。つまり、変更しようとはしません。