# Convert Numpy Arrays to Julia Arrays by Default PythonCall/JuliaCall

**URL:** <https://discourse.julialang.org/t/convert-numpy-arrays-to-julia-arrays-by-default-pythoncall-juliacall/90671>\
**Category:** General Usage\
**Tags:** question, package, type, juliacall, pythoncall\
**Created:** [November 22, 2022, 10:07pm UTC](https://discourse.julialang.org/t/convert-numpy-arrays-to-julia-arrays-by-default-pythoncall-juliacall/90671 "2022-11-22T22:07:34Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![leespen1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leespen1/32/221928_2.png) [@leespen1](https://discourse.julialang.org/u/leespen1)\
**Post date:** [November 22, 2022, 10:07pm UTC](https://discourse.julialang.org/t/convert-numpy-arrays-to-julia-arrays-by-default-pythoncall-juliacall/90671/1 "2022-11-22T22:07:34Z")

</div>

I am currently writing an interface between a Python program and a Julia Package; I would like to call the functions in the Julia package from Python. The functions in the Julia package all have type declarations, and for better or for worse, I am not able to change this . I could do is write function wrappers for all functions in the package, but I would like to avoid that if possible.

When the Julia functions have basic type declarations, like `Int64`, `Float`, or `Bool`, the conversion seems to happen, but not for numpy arrays.

Is there a way to have PythonCall/JuliaCall automatically convert numpy arrays into Julia arrays when passing them as arguments to a function? For example, I would like to define the Julia function:

```julia
function matrix_func(x::Array{Float64, 2})
    Do some stuff
end

```

And then, on the Python side:

```julia
import numpy as np
from juliacall import Main as jl

my_array = np.array([[1,2,3], [4,5,6]])
jl.include("File containing matrix_func definition")
jl.matrix_func(my_array)

```

For my use case, I am completely fine with performing copying operations. I am aware that copying operations will allocate memory unnecessarily, but in my case I’m only calling a few functions from Julia to set up a Julia object which contains all the data needed for our task, after which everything will be done in Julia.

According to the documentation here: [Python to Julia · PythonCall & JuliaCall](https://cjdoris.github.io/PythonCall.jl/dev/conversion-to-julia/), the user can set custom conversion rules, but I do not understand whether I can make use of this to perform automatic type conversion when calling Julia functions from Python, or if this is only for implementing/overriding the behavior for when the user calls `pyconvert` directly.

---

<div class="post-metadata">

**Author:** ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)\
**Post date:** [November 23, 2022, 3:33am UTC](https://discourse.julialang.org/t/convert-numpy-arrays-to-julia-arrays-by-default-pythoncall-juliacall/90671/2 "2022-11-23T03:33:36Z")

</div>

> [@leespen1](#):
>
> ```julia-auto
> function matrix_func(x::Array{Float64, 2})
> Do some stuff
> end
> 
> ```

You can be less restrictive in the type; instead do:

```julia-auto
function matrix_func(x::AbstractArray)
...

```

The reason is that `np.ndarray` is converted to `PyArray`, which is a subtype of a Julia `AbstractArray{T,N}`. cf. [Redirecting to https://juliapy.github.io/PythonCall.jl/dev/pythoncall-reference/](https://cjdoris.github.io/PythonCall.jl/dev/pythoncall-reference/#PythonCall.PyArray)

---

<div class="post-metadata">

**Author:** ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)\
**Post date:** [November 23, 2022, 6:36pm UTC](https://discourse.julialang.org/t/convert-numpy-arrays-to-julia-arrays-by-default-pythoncall-juliacall/90671/3 "2022-11-23T18:36:52Z")

</div>

@jd-foster’s answer is excellent, but it sounds like you do not have control over the Julia functions you are calling. In which case, you’ll need to do some explicit conversion.

The simplest way is to instead call

```python
jl.matrix_func(juliacall.convert(jl.Array[jl.Float64, 2], my_array))

```

which explicitly converts `my_array` to an `Array{Float64, 2}` before passing it to the function.

Or you could create a new Julia function

```python
jl.seval("matrix_func_wrapped(x) = matrix_func(convert(Matrix, x))")
jl.matrix_func_wrapped(my_array)

```

or if you’re happy with piracy you could add a method to `matrix_func`:

```python
jl.seval("matrix_func(x) = matrix_func(convert(Matrix{Float64}, x))")
jl.matrix_func(my_array)

```

---

<div class="post-metadata">

**Author:** ![leespen1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leespen1/32/221928_2.png) [@leespen1](https://discourse.julialang.org/u/leespen1)\
**Post date:** [November 25, 2022, 11:27pm UTC](https://discourse.julialang.org/t/convert-numpy-arrays-to-julia-arrays-by-default-pythoncall-juliacall/90671/4 "2022-11-25T23:27:10Z")

</div>

I agree that this would be a good solution, but unfortunately in practice `matrix_func` is defined in a package which I am not allowed to alter (if I could, I would). But like you said, `np.ndarray` is converted to `PyArray`. Is there a way to have it instead be converted to `Array{T,N}`? Or would this require a pretty substantial rewrite of PythonCall/JuliaCall?

---

<div class="post-metadata">

**Author:** ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)\
**Post date:** [November 26, 2022, 11:08am UTC](https://discourse.julialang.org/t/convert-numpy-arrays-to-julia-arrays-by-default-pythoncall-juliacall/90671/5 "2022-11-26T11:08:57Z")

</div>

Of course, I should have read your question more closely.  
The answer from cjdoris is fairly definitive, given that he is the developer of PythonCall and JuliaCall.

---

<div class="post-metadata">

**Author:** ![leespen1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leespen1/32/221928_2.png) [@leespen1](https://discourse.julialang.org/u/leespen1)\
**Post date:** [November 28, 2022, 9:51pm UTC](https://discourse.julialang.org/t/convert-numpy-arrays-to-julia-arrays-by-default-pythoncall-juliacall/90671/6 "2022-11-28T21:51:14Z")

</div>

Thanks! I think wrapping/pirating the original function will be the most convenient method for me in the long term. I appreciate the help!
