py4u blog

How to Install NumPy Package in Julia?

Julia is a high-performance programming language for technical computing, but there are scenarios where leveraging Python’s NumPy (a fundamental package for scientific computing) is necessary—e.g., reusing Python code, integrating with Python libraries, or leveraging NumPy’s extensive ecosystem. This blog explains how to install and use NumPy in Julia using two popular bridges: PyCall (mature) and PythonCall (modern).

2026-07

Table of Contents#

  1. Prerequisites
  2. Methods to Use NumPy in Julia
  3. Step-by-Step Installation Guide
  4. Example Usage of NumPy in Julia
  5. Best Practices
  6. Common Pitfalls and Solutions
  7. Conclusion
  8. References

Prerequisites#

Before proceeding, ensure:

  • Julia (≥1.0; latest stable version recommended) is installed.
  • Python (≥3.6; check with python --version or python3 --version in a terminal) is installed.
  • Familiarity with Julia’s package manager (Pkg) and Python’s package managers (pip/conda).

Methods to Use NumPy in Julia #

Two primary packages enable NumPy usage in Julia:

1. Using PyCall #

PyCall is a mature Julia package that provides a bridge to Python. It allows calling Python functions (including NumPy) from Julia.

  • Pros: Widely used, integrates with Julia’s type system (with conversions).
  • Cons: Type conversions can be error-prone; Python environment management is challenging.

2. Using PythonCall #

PythonCall is a modern package with better interoperability (automatic type conversions, virtual environment support).

  • Pros: Modern, robust type handling, native virtual environment support.
  • Cons: Less legacy support (but growing in popularity).

Step-by-Step Installation Guide #

Installing NumPy with PyCall #

  1. Install PyCall:
    In Julia’s REPL, enter package mode (]) and run:

    (@v1.9) pkg> add PyCall
  2. Configure Python for PyCall:
    PyCall can use a system Python or a Conda-managed Python (recommended for isolation):

    • Option 1: System Python (simpler but risky for version conflicts):
      Ensure Python is in your PATH. Verify by running:

      using PyCall
      pyimport("sys")[:version]  # Prints Python version
    • Option 2: Conda-Managed Python (recommended):
      Install Conda.jl (to manage Python environments):

      (@v1.9) pkg> add Conda

      Use Conda to install Python and NumPy:

      using Conda
      Conda.add("python"; channel="defaults")  # Install Python
      Conda.add("numpy"; channel="defaults")   # Install NumPy

      Reconfigure PyCall to use Conda’s Python:

      ENV["PYTHON"] = ""  # Let PyCall detect Conda’s Python
      Pkg.build("PyCall")

      Restart Julia after building.

Installing NumPy with PythonCall #

  1. Install PythonCall:
    In Julia’s REPL (package mode):

    (@v1.9) pkg> add PythonCall
  2. Install NumPy via pip/conda:
    Ensure Python is in your PATH (or use a virtual environment).

    • Using pip:
      In a terminal (or Julia’s shell mode ;):

      pip install numpy
    • Using conda:

      conda install numpy
  3. Verify in Julia:

    using PythonCall
    np = pyimport("numpy")
    println(np.__version__)  # Prints NumPy version

Example Usage of NumPy in Julia #

Example 1: Basic Array Operations (PyCall)#

using PyCall
 
# Import NumPy
np = pyimport("numpy")
 
# Create a NumPy array
arr_py = np.array([1, 2, 3, 4, 5])
println("NumPy array: ", arr_py)       # Output: NumPy array: [1 2 3 4 5]
println("Type in Julia: ", typeof(arr_py))  # PyCall.PyObject
 
# Convert to Julia array
arr_jl = convert(Array, arr_py)
println("Julia array: ", arr_jl)       # Output: Julia array: [1, 2, 3, 4, 5]
println("Type in Julia: ", typeof(arr_jl))  # Array{Int64,1}
 
# Sum via NumPy
sum_py = np.sum(arr_py)
println("Sum (NumPy): ", sum_py)       # Output: Sum (NumPy): 15
 
# Sum via Julia
sum_jl = sum(arr_jl)
println("Sum (Julia): ", sum_jl)       # Output: Sum (Julia): 15

Example 2: Linear Algebra (PythonCall)#

using PythonCall
 
# Import NumPy
np = pyimport("numpy")
 
# Create a 2D matrix
mat_py = np.array([[1, 2], [3, 4]])
println("NumPy matrix: ", mat_py)  # Output: NumPy matrix: [[1 2]
                                   #                  [3 4]]
 
# Matrix multiplication (dot product)
mat_product = np.dot(mat_py, mat_py)
println("Matrix product (NumPy): ", mat_product)  # Output: [[ 7 10]
                                                  #          [15 22]]
 
# Convert to Julia Matrix (optional)
mat_jl = pyconvert(Matrix, mat_py)
println("Julia matrix: ", mat_jl)  # Output: Julia matrix: [1 2; 3 4]
 
# Julia matrix multiplication
mat_product_jl = mat_jl * mat_jl
println("Matrix product (Julia): ", mat_product_jl)  # Output: [7 10; 15 22]

Example 3: Broadcasting (PythonCall)#

using PythonCall
 
np = pyimport("numpy")
 
# 2D array + 1D array (broadcasting)
arr_2d = np.array([[1, 2], [3, 4]])
arr_1d = np.array([10, 20])
 
# NumPy-style broadcasting (Julia’s broadcast via `.+`)
result = arr_2d .+ arr_1d
println("Broadcasting result: ", result)  # Output: [[11 22]
                                          #          [13 24]]

Best Practices #

  1. Isolate Environments: Use virtual environments (Python’s venv/conda, or Julia’s Project.toml/Manifest.toml) to avoid conflicts.
  2. Version Compatibility: Ensure Julia, PyCall/PythonCall, Python, and NumPy versions are compatible (e.g., NumPy 1.23+ requires Python 3.8+).
  3. Type Handling:
    • Use pyconvert (PythonCall) or convert (PyCall) for explicit type conversions.
    • Minimize conversions in performance-critical code (work directly with PyObject).
  4. Documentation: Document Python/NumPy versions (e.g., in README.md or Project.toml).

Common Pitfalls and Solutions #

  1. Python Not Found:

    • Symptom: “Python not found” error.
    • Solution: Set ENV["PYTHON"] to the Python executable path (e.g., ENV["PYTHON"] = "/path/to/python"), then rebuild PyCall/PythonCall.
  2. Version Mismatches:

    • Symptom: Import errors (e.g., “numpy not found”).
    • Solution: Use Conda to manage Python/NumPy versions (e.g., Conda.add("numpy"; version="1.23")).
  3. Type Conversion Errors:

    • Symptom: “Cannot convert PyObject to Array” errors.
    • Solution: Explicitly convert types (e.g., pyconvert(Matrix, pyobj) for PythonCall).

Conclusion#

Using NumPy in Julia is feasible via PyCall (mature) or PythonCall (modern). Choose the method that aligns with your project’s needs (legacy workflows vs. modern, type-safe integration). Prioritize environment isolation, version compatibility, and explicit type handling for a smooth experience.

References#