# PythonCall array indexing

**URL:** <https://discourse.julialang.org/t/pythoncall-array-indexing/97099>\
**Category:** General Usage\
**Tags:** question, pythoncall\
**Created:** [April 5, 2023, 7:13am UTC](https://discourse.julialang.org/t/pythoncall-array-indexing/97099 "2023-04-05T07:13:43Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![polhager](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/polhager/32/37340_2.png) [@polhager](https://discourse.julialang.org/u/polhager)\
**Post date:** [April 5, 2023, 7:13am UTC](https://discourse.julialang.org/t/pythoncall-array-indexing/97099/1 "2023-04-05T07:13:43Z")

</div>

Hello! In trying to use PythonCall in place of PyCall I find a strange behaviour when indexing a matrix in Python using only one index. As an example, I have the python file `pythoncall_test.py`:

```py
def test(q):
    return q[0]

```

If I send a vector to this function, I expect the first element. If I send a matrix, I expect the first row. However:

```julia
julia> using PythonCall

julia> pyimport("pythoncall_test").test(zeros(3))
Python float: 0.0

julia> pyimport("pythoncall_test").test([1 2 3; 4 5 6; 7 8 9])
ERROR: Python: Julia: an error occurred while setting an error
Python stacktrace:
 [1] __getitem__
   @ ~/.julia/packages/PythonCall/dsECZ/src/jlwrap/array.jl:308
 [2] test
   @ pythoncall_test ~/git/vibdamp-22/pythoncall_test.py:2
Stacktrace:
 [1] pythrow()
   @ PythonCall ~/.julia/packages/PythonCall/dsECZ/src/err.jl:94
 [2] errcheck
   @ ~/.julia/packages/PythonCall/dsECZ/src/err.jl:10 [inlined]
 [3] pycallargs(f::Py, args::Py)
   @ PythonCall ~/.julia/packages/PythonCall/dsECZ/src/abstract/object.jl:210
 [4] pycall(f::Py, args::Matrix{Int64}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ PythonCall ~/.julia/packages/PythonCall/dsECZ/src/abstract/object.jl:228
 [5] pycall
   @ ~/.julia/packages/PythonCall/dsECZ/src/abstract/object.jl:218 [inlined]
 [6] #_#11
   @ ~/.julia/packages/PythonCall/dsECZ/src/Py.jl:352 [inlined]
 [7] (::Py)(args::Matrix{Int64})
   @ PythonCall ~/.julia/packages/PythonCall/dsECZ/src/Py.jl:352
 [8] top-level scope
   @ REPL[4]:1

```

Running the same code with PyCall instead provides the expected result:

```julia
julia> using PyCall

julia> pyimport("pythoncall_test").test(zeros(3))
0.0

julia> pyimport("pythoncall_test").test([1 2 3; 4 5 6; 7 8 9])
3-element Vector{Int64}:
 1
 2
 3

```

Why does this happen? Is this a known limitation of PythonCall or is there a fix?

---

<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:** [April 11, 2023, 7:09am UTC](https://discourse.julialang.org/t/pythoncall-array-indexing/97099/2 "2023-04-11T07:09:56Z")

</div>

I’m not sure if you figured this out, but as I understand PythonCall does not do automatic conversions as readily as PyCall.  
See [Julia to Python · PythonCall & JuliaCall](https://cjdoris.github.io/PythonCall.jl/dev/conversion-to-python/) for the conversion rules, where `Matrix` does not have an explicit conversion. See also [Coming from PyCall/PyJulia? · PythonCall & JuliaCall](https://cjdoris.github.io/PythonCall.jl/dev/pycall/)

To do what you seemed to expect coming from PyCall, you can use the [`pyrowlist`](https://cjdoris.github.io/PythonCall.jl/dev/pythoncall-reference/#PythonCall.pyrowlist) function to do the type conversion to Python:

```julia
julia> ct = pyimport("call_test")
Python module: <module 'call_test' from ....>

julia> M
3×3 Matrix{Int64}:
 1 2 3
 4 5 6
 7 8 9

julia> ct.test(pyrowlist(M))
Python list: [1, 2, 3]

julia> ct.my_test(pyrowlist(M)) |> collect
3-element Vector{Py}:
 1
 2
 3

```

---

<div class="post-metadata">

**Author:** ![polhager](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/polhager/32/37340_2.png) [@polhager](https://discourse.julialang.org/u/polhager)\
**Post date:** [April 11, 2023, 8:15am UTC](https://discourse.julialang.org/t/pythoncall-array-indexing/97099/3 "2023-04-11T08:15:05Z")

</div>

This solves the issue, thanks!

However I now run into another issue which again PyCall doesn’t have a problem with. I want to find the rows in a matrix for which at least one element has a value above a given threshold. `PythonCall` doesn’t seem to like mask indexing. “pythoncall\_test.py”:

```py
import numpy as np

def test(q, thres):
    q_ok = np.any(np.abs(q) > thres, axis=1)
    return q[q_ok]

```

In Julia:

```julia
julia> using PythonCall

julia> pyimport("pythoncall_test").test(pyrowlist([1 2 3; 4 5 6; 7 8 9]), 5)
ERROR: Python: TypeError: only integer scalar arrays can be converted to a scalar index
Python stacktrace:
 [1] test
   @ pythoncall_test ~/git/vibdamp-22/pythoncall_test.py:5
Stacktrace:
 [1] pythrow()
   @ PythonCall ~/.julia/packages/PythonCall/dsECZ/src/err.jl:94
 [2] errcheck
   @ ~/.julia/packages/PythonCall/dsECZ/src/err.jl:10 [inlined]
 [3] pycallargs(f::Py, args::Py)
   @ PythonCall ~/.julia/packages/PythonCall/dsECZ/src/abstract/object.jl:210
 [4] pycall(::Py, ::Py, ::Vararg{Any}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ PythonCall ~/.julia/packages/PythonCall/dsECZ/src/abstract/object.jl:228
 [5] pycall(::Py, ::Py, ::Vararg{Any})
   @ PythonCall ~/.julia/packages/PythonCall/dsECZ/src/abstract/object.jl:218
 [6] (::Py)(::Py, ::Vararg{Any}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ PythonCall ~/.julia/packages/PythonCall/dsECZ/src/Py.jl:352
 [7] (::Py)(::Py, ::Vararg{Any})
   @ PythonCall ~/.julia/packages/PythonCall/dsECZ/src/Py.jl:352
 [8] top-level scope
   @ REPL[3]:1

```

Again, `PyCall` doesn’t struggle:

```julia
julia> using PyCall

julia> pyimport("pythoncall_test").test([1 2 3; 4 5 6; 7 8 9], 5)
2×3 Matrix{Int64}:
 4 5 6
 7 8 9

```

Any ideas here?

---

<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:** [April 12, 2023, 6:45am UTC](https://discourse.julialang.org/t/pythoncall-array-indexing/97099/4 "2023-04-12T06:45:00Z")

</div>

See [FAQ & Troubleshooting · PythonCall & JuliaCall](https://cjdoris.github.io/PythonCall.jl/dev/faq/#Issues-when-Numpy-arrays-are-expected)

```julia
julia> using PythonCall

julia> M = [1 2 3; 4 5 6; 7 8 9]

julia> pyimport("pythoncall_test").test(Py(M).to_numpy(), 5)

```
