Indexing and Slicing
Accessing and modifying elements, rows, columns, and sub-arrays of INDArrays using NDArrayIndex
This page explains how to read and write individual values, rows, columns, and arbitrary sub-arrays of an INDArray. It also covers sequential iteration, tensor-along-dimension, boolean indexing, and converting NDArrays to plain Java arrays.
A note on views vs. copies
Many of the operations described on this page return a view, not a copy. A view is an INDArray that shares the same underlying off-heap memory as the original array. Mutations made through the view are immediately visible in the original, and vice-versa.
Operations that return views include getRow(), getColumn(), get(NDArrayIndex...) with NDArrayIndex.point(), .all(), or .interval(), tensorAlongDimension(), transpose(), and reshape().
Operations that return copies (new allocations) include getRows(int...), dup(), and toDoubleVector() / toDoubleMatrix().
When you need an independent copy of a view, call .dup() on the result:
INDArray rowCopy = myArray.getRow(0).dup(); // independent copy1. Getting and Setting Individual Values
For an INDArray of rank N, you need N indices to address a single element. Indexing is zero-based: rows range from 0 to size(0)-1, columns from 0 to size(1)-1, and so on.
Performance note: Reading or writing one element at a time in a loop is expensive because each call crosses the JVM/off-heap boundary. Prefer bulk operations (ops, slices,
assign()) whenever possible.
Reading single values
INDArray arr = Nd4j.create(new double[][]{
{1.0, 2.0, 3.0},
{4.0, 5.0, 6.0},
{7.0, 8.0, 9.0}
});
// getDouble(int row, int col) -- 2D shorthand
double val = arr.getDouble(1, 2);
// 6.0
// getDouble(int...) -- works for any rank
double same = arr.getDouble(1, 2);
// 6.0
// getFloat / getInt -- same signatures, different return type
float f = arr.getFloat(0, 0);
// 1.0
int i = arr.getInt(2, 1);
// 8For 3D or higher arrays supply three or more indices:
Writing single values: putScalar
Overloads also accept float and int values:
2. Row and Column Access
Getting rows
getRow(int) returns a view of a single row as a row vector:
Because row1 is a view, modifying it modifies arr as well:
To add to a row without keeping a reference, chain the call directly:
Getting multiple rows
getRows(int...) stacks the requested rows into a new matrix. This returns a copy, not a view:
Setting a row: putRow
Getting a column
getColumn(int) returns a view of a single column as a column vector:
Like getRow, this is a view -- writes to col0 affect arr.
3. NDArrayIndex-Based Access
The INDArray.get(NDArrayIndex...) family provides the most general sub-array access. You supply one NDArrayIndex per dimension; ND4J resolves which elements to include along each axis and returns a view of the result.
Import required:
NDArrayIndex.point(int)
Selects a single index along a dimension, collapsing that dimension:
NDArrayIndex.all()
Selects every index along a dimension (equivalent to : in NumPy):
NDArrayIndex.interval(int from, int to)
Selects indices [from, to) (inclusive start, exclusive end):
NDArrayIndex.interval(int from, int stride, int to)
Selects every stride-th index between from (inclusive) and to (exclusive):
NDArrayIndex.specified(long...)
Selects an explicit, possibly non-contiguous set of indices. This is the equivalent of fancy/advanced indexing:
Combining NDArrayIndex types
All four index types can be mixed freely across dimensions:
Extending to 1D arrays
For a 1D array (vector) provide a single NDArrayIndex:
4. Put Operations: Writing to Sub-Arrays
put(INDArrayIndex[], INDArray)
The counterpart to get -- writes the values of toPut into the sub-array identified by the index array:
The shape of patch must match the shape implied by the provided indices, or ND4J will throw.
Equivalence with get().assign()
Because get(NDArrayIndex...) returns a view, the two forms below are exactly equivalent:
Both overwrite the data in arr in place. Choose whichever reads more clearly.
Assigning a scalar to a slice
Combine get() and assign(double) to fill a region with a constant:
5. Tensor Along Dimension
Tensor Along Dimension (TAD) extracts a lower-rank sub-array from a higher-rank array. The result is always a view. TAD is particularly useful when you need to apply the same operation to every "slice" of an array along some set of dimensions.
Core method signatures
Note the double-s in tensorssAlongDimension -- that is the actual method name.
2D example
Shape rules for TAD
The shape of each returned tensor and the number of tensors are determined as follows:
[a, b, c]
(0)
b * c
[1, a]
[a, b, c]
(1)
a * c
[1, b]
[a, b, c]
(0, 1)
c
[a, b]
[a, b, c]
(1, 2)
a
[b, c]
[a,b,c,d]
(1, 2)
a * d
[b, c]
[a,b,c,d]
(0, 2, 3)
b
[a, c, d]
3D example: iterating over 2D slices
Because TAD returns views, you can mutate each slice and the changes propagate back to volume.
6. Converting to Java Arrays
Sometimes you need a plain Java array for interoperability with existing code. ND4J provides several conversion methods. All of them allocate new Java heap arrays (copies, not views).
1D arrays
2D arrays
These methods only work for 1D and 2D arrays respectively. For higher-rank arrays, flatten first with ravel() or use getDouble(int[]) in a loop.
7. NdIndexIterator: Sequential Traversal
NdIndexIterator traverses all elements of an INDArray in C-order (row-major), producing the index tuple for each element in turn. The traversal order for a rank-2 array is [0,0], [0,1], ..., [0,n-1], [1,0], ....
For arrays with 3 or more dimensions, pass the full shape to the constructor:
NdIndexIterator is useful when you genuinely need to visit every element, for example to build a sparse representation or apply a predicate that cannot be vectorised. For most bulk operations, use ND4J ops instead.
8. Boolean Indexing
The BooleanIndexing class applies operations to elements of an array that satisfy a condition, without needing explicit index calculations.
Replace values that match a condition
Apply a value from a second array where condition holds
Available conditions
Conditions.lessThan(x)
element < x
Conditions.lessThanOrEqual(x)
element <= x
Conditions.greaterThan(x)
element > x
Conditions.greaterThanOrEqual(x)
element >= x
Conditions.equals(x)
element == x
Conditions.notEquals(x)
element != x
Conditions.isNan()
element is NaN
Conditions.isInfinite()
element is +/-Inf
Conditions.isFinite()
element is finite (not NaN, not Inf)
Conditions.absGreaterThan(x)
The full list and the unit tests for BooleanIndexing can be found in the BooleanIndexingTest source file.
9. Views in Depth: What Is and Is Not a View
Understanding whether an operation returns a view or a copy prevents subtle bugs.
Operations that return views
Modifying any of v1-v7 will modify a (and vice versa).
Operations that return copies
Forcing a copy
Call .dup() on any view to obtain an independent array:
Quick Reference
Single element (double)
arr.getDouble(int, int)
double
Single element (float)
arr.getFloat(int)
float
Single element (any rank)
arr.getDouble(new int[]{i,j,k})
double
Write single element
arr.putScalar(new int[]{i,j}, v)
INDArray (this)
Whole row
arr.getRow(int)
VIEW
Multiple rows
arr.getRows(int...)
copy
Write a row
arr.putRow(int, INDArray)
INDArray (this)
Whole column
arr.getColumn(int)
VIEW
Point index
arr.get(NDArrayIndex.point(i), ...)
VIEW
Range
arr.get(NDArrayIndex.interval(a,b), ...)
VIEW
Strided range
arr.get(NDArrayIndex.interval(a,stride,b), ...)
VIEW
All elements on axis
arr.get(NDArrayIndex.all(), ...)
VIEW
Explicit indices
arr.get(NDArrayIndex.specified(0,2), ...)
VIEW
Write sub-array
arr.put(INDArrayIndex[], INDArray)
INDArray (this)
TAD count
arr.tensorssAlongDimension(int...)
long
TAD slice
arr.tensorAlongDimension(int, int...)
VIEW
Java double[]
arr.toDoubleVector()
copy
Java double[][]
arr.toDoubleMatrix()
copy
Java float[]
arr.toFloatVector()
copy
Sequential iteration
new NdIndexIterator(long...)
iterator
Boolean replace
BooleanIndexing.replaceWhere(arr, val, cond)
void (in-place)
See Also
ND4J Overview -- full programming guide including creation, operations, and serialization
ND4J Quickstart -- brief tour of the most common operations
Last updated
Was this helpful?