PyDotNet.NumPy 1.0.0

dotnet add package PyDotNet.NumPy --version 1.0.0
                    
NuGet\Install-Package PyDotNet.NumPy -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PyDotNet.NumPy" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PyDotNet.NumPy" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="PyDotNet.NumPy" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add PyDotNet.NumPy --version 1.0.0
                    
#r "nuget: PyDotNet.NumPy, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package PyDotNet.NumPy@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=PyDotNet.NumPy&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=PyDotNet.NumPy&version=1.0.0
                    
Install as a Cake Tool

PyDotNet.NumPy

A typed NumPy plugin for PyDotNet — zero-copy interop between .NET memory and NumPy arrays via DLPack, with async reducers that exploit NumPy's GIL-free computation.

Installation

dotnet add package PyDotNet.NumPy

NumPy must be installed in the active Python environment:

pip install numpy

Quick start

using PyDotNet.NumPy;
using PyDotNet.Runtime;

PyRuntime.Initialize(new PyRuntimeOptions { ReleaseGilAfterInit = true });

using var interp = PyRuntime.CreateInterpreter();
using var np     = NumpyModule.Import(interp);

// Create arrays
using var zeros = np.Zeros<float>(3, 4);        // 3×4 float32 zeros
using var ones  = np.Ones<double>(100);          // 100-element float64 ones

// Arithmetic operators
using var a = np.Arange<float>(0f, 6f, 1f);
using var b = np.Full<float>(new long[] { 6 }, 2f);
using var c = a * b + 1f;

// Reducers
double mean = ones.Mean();
double std  = ones.Std();

PyRuntime.Shutdown();

Zero-copy interop

FromMemory<T> exports a .NET Memory<T> to NumPy via DLPack — no data is copied. The C# memory is pinned by the DLPack deleter and unpinned automatically when NumPy's array is garbage-collected.

float[] prices = { 100f, 102f, 98f, 105f, 110f };
using var arr = np.FromMemory<float>(prices.AsMemory());

// Write-through: modifying the span updates the C# array
arr.AsSpan<float>()[0] = 99f;
Console.WriteLine(prices[0]);   // 99

// Changes to the C# array are immediately visible in NumPy
prices[4] = 115f;
Console.WriteLine(arr.Sum());   // 99 + 102 + 98 + 105 + 115 = 519

For read-only scenarios where the source is a temporary span, use FromSpan<T> (copies once):

using var copy = np.FromSpan<double>(stackalloc double[] { 1.0, 2.0, 3.0 });

Async reducers

NumPy releases the GIL during BLAS-accelerated computation. The async reducer methods run reductions on the .NET thread pool, enabling true concurrency across multiple arrays:

using var a = np.Random.Normal(new long[] { 1_000_000 });
using var b = np.Random.Normal(new long[] { 1_000_000 });
using var c = np.Random.Normal(new long[] { 1_000_000 });

// All three reductions proceed in parallel at the native level
var (meanA, meanB, meanC) = await (a.MeanAsync(), b.MeanAsync(), c.MeanAsync())
    .WhenAll();   // helper pattern — or use Task.WhenAll directly

API reference

NumpyModule

Member Description
static Import(PyInterpreter) Import numpy and return a new module wrapper.
Zeros<T>(params long[] shape) Array of zeros, typed by T.
Ones<T>(params long[] shape) Array of ones.
Arange<T>(T start, T stop, T step) Evenly spaced range.
LinSpace<T>(T start, T stop, long num) Linearly spaced values (endpoints inclusive).
Eye<T>(long n) Identity matrix of size n×n.
Full<T>(long[] shape, T fill) Array filled with a constant.
FromMemory<T>(Memory<T>, long[] shape) Zero-copy — DLPack export, no allocation.
FromMemory<T>(Memory<T>) Zero-copy 1-D shorthand.
FromSpan<T>(ReadOnlySpan<T>, long[]?) Copies span then zero-copy wraps.
Add / Subtract / Multiply / Divide Element-wise ufuncs.
Abs / Sqrt / Square / Exp / Log Unary ufuncs.
MatMul(a, b) Matrix multiplication (numpy.matmul).
Stack(NdArray[], int axis) Stack along a new axis.
Concatenate(NdArray[], int axis) Concatenate along an existing axis.
ExpandDims(NdArray, int axis) Insert a new axis.
AsContiguousArray(NdArray) Return C-contiguous copy if needed.
Where(condition, x, y) Element-wise conditional selection (numpy.where).
Log2(a) / Log10(a) Base-2 / base-10 logarithm.
Power(a, exponent) Element-wise power (numpy.power).
Clip(a, min, max) Module-level element-wise clamp.
Sort(a) Returns sorted copy (last axis, numpy.sort).
ArgSort(a) Returns sort-indices array (numpy.argsort).
BroadcastTo(a, shape) Broadcast to shape without copying (read-only).
Pad(a, before, after, mode) Pad all axes uniformly (numpy.pad).
Unique(a) Sorted unique elements (numpy.unique).
Tile(a, reps) Repeat array along each axis (numpy.tile).
Random NumpyRandom sub-object.

NdArray

Member Description
Shape IReadOnlyList<long> — dimensions.
Rank Number of dimensions.
ElementCount Total element count.
DType NumpyDType enum.
IsOnGpu True for GPU arrays (CuPy etc.).
IsContiguous True for C-contiguous layout.
AsSpan<T>() Zero-copy read/write span (CPU, contiguous).
AsReadOnlySpan<T>() Zero-copy read-only span.
ToArray<T>() Copies to a new managed array.
Reshape(params long[]) Returns a view with new shape.
Transpose() Axes transposed (typically non-contiguous).
Flatten() 1-D C-contiguous copy.
Squeeze() Remove all size-1 dimensions.
Copy() C-contiguous copy.
AsType(NumpyDType) Type-cast copy.
Clip(min, max) Element-wise clamp.
Dot(NdArray) Dot product.
MatMul(NdArray) Matrix multiplication (@).
SumAxis(int) / MeanAxis(int) Reduce along one axis (returns NdArray).
VarAxis(int) / StdAxis(int) Variance / std deviation along one axis.
Sum / Mean / Std / Var / Min / Max Scalar reducers.
ArgMin() / ArgMax() Flat index of minimum / maximum element.
ArgSort() Indices that would sort the array (last axis).
Sorted() Returns a sorted copy (does not mutate).
Cumsum() / Cumprod() Cumulative sum / product (flattened).
Round(int decimals) Element-wise rounding.
Fill(double value) In-place fill with a constant.
SumAsync / MeanAsync / StdAsync / MinAsync / MaxAsync Async thread-pool reducers.
+ − × / Element-wise operators (NdArray and scalar).
AsPyObject() Access the raw PyObject for advanced interop.

NumpyRandom

Accessed via NumpyModule.Random.

Member Description
Seed(int) Set the random seed.
Normal(shape, loc, scale) Normal distribution.
Uniform(shape, low, high) Uniform distribution.
Integers(low, high, shape) Random integers.
Standard(shape) Standard normal (μ=0, σ=1).
Exponential(shape, scale) Exponential distribution.
Poisson(shape, lam) Poisson distribution.
Choice(n, shape, replace) Random samples from arange(n).
Permutation(n) Random permutation of [0, n).

Real-world examples

Portfolio statistics

double[] dailyReturns = GetDailyReturns();
using var ret = np.FromMemory<double>(dailyReturns.AsMemory());

var annReturn = ret.Mean() * 252.0;
var annVol    = ret.Std()  * Math.Sqrt(252.0);
var sharpe    = annReturn / annVol;

Matrix chain (A @ B + bias)

using var A    = np.Random.Normal(new long[] { 128, 256 });
using var B    = np.Random.Normal(new long[] { 256, 64 });
using var bias = np.Zeros<double>(128, 64);

using var AB = np.MatMul(A, B);
using var C  = AB + bias;

Z-score normalisation

using var data = np.Random.Normal(new long[] { 100_000 }, loc: 50.0, scale: 15.0);
using var z    = (data - data.Mean()) / data.Std();
// z is now standardised: mean ≈ 0, std ≈ 1

Parallel async reductions

using var batches = Enumerable.Range(0, 8)
    .Select(_ => np.Random.Normal(new long[] { 500_000 }))
    .ToArray();

var means = await Task.WhenAll(batches.Select(b => b.MeanAsync()));
foreach (var b in batches) { b.Dispose(); }

Lifetime and disposal

All NdArray objects returned by NumpyModule and arithmetic operators are owned by the caller and must be disposed:

using var a = np.Zeros<float>(1000);   // ✅ owned, will be disposed
var b = np.Ones<float>(1000);          // ⚠ must call b.Dispose() manually

For zero-copy arrays created with FromMemory<T>, the C# backing memory must remain valid until the NdArray is disposed AND the Python GC has collected the internal capsule. In practice, this means keep the backing array alive as long as the NdArray is in scope.

Notes

  • Requires NumPy ≥ 1.22 (DLPack protocol support).
  • GPU arrays (CuPy, JAX) are supported for Python-level operations; AsSpan<T> requires CPU arrays.
  • Transpose() returns a non-contiguous view; call Copy() or Flatten() before AsSpan<T>.
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 88 5/25/2026