How to Get a Dimension (Slice) from a Multidimensional Array

How to get a dimension (slice) from a multidimensional array

No. You could of course write a wrapper class that represents a slice, and has an indexer internally - but nothing inbuilt. The other approach would be to write a method that makes a copy of a slice and hands back a vector - it depends whether you want a copy or not.

using System;
static class ArraySliceExt
{
public static ArraySlice2D<T> Slice<T>(this T[,] arr, int firstDimension)
{
return new ArraySlice2D<T>(arr, firstDimension);
}
}
class ArraySlice2D<T>
{
private readonly T[,] arr;
private readonly int firstDimension;
private readonly int length;
public int Length { get { return length; } }
public ArraySlice2D(T[,] arr, int firstDimension)
{
this.arr = arr;
this.firstDimension = firstDimension;
this.length = arr.GetUpperBound(1) + 1;
}
public T this[int index]
{
get { return arr[firstDimension, index]; }
set { arr[firstDimension, index] = value; }
}
}
public static class Program
{
static void Main()
{
double[,] d = new double[,] { { 1, 2, 3, 4, 5 }, { 5, 4, 3, 2, 1 } };
var slice = d.Slice(0);
for (int i = 0; i < slice.Length; i++)
{
Console.WriteLine(slice[i]);
}
}
}

How to slice a two dimensional array?

You need to map the sliced arrays.

const
array = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]],
customSlice = array => array.slice(1, 3),
result = array.map(customSlice);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

tuple as index in multidimensional array together with slicing

You can do the following:

import numpy as np

A = np.arange(12).reshape((2, 3, 2))
print(A)

x = [1, 1]
print(A[(slice(None), *x)])

You can use slice(None) instead of : to build a tuple of slices. The tuple environment allows for value unpacking with the * operator.

Output:

[[[ 0  1]
[ 2 3]
[ 4 5]]

[[ 6 7]
[ 8 9]
[10 11]]]

[3 9]

To verify it matches:

import numpy as np

A = np.arange(12).reshape((2, 3, 2))
x = [1, 1]
s = (slice(None), *x)
print(np.allclose(A[s], A[:, 1, 1])) # True

*This is a modification of answers found here: Slicing a numpy array along a dynamically specified axis


Edit to reflect edit on question and comment:

To clarify, you can unpack any iterable you like in the tuple environment. The * operator functions normally in within the tuple. Order your elements however you like. Mix in different iterables, types, slice(None), how ever you want to build your slices, as long as you end up with a valid sequence of values, it will behave as expected.

import numpy as np

A = np.arange(12).reshape((2, 3, 2))
t = [True, False]
x = [1, 1]
print(np.allclose(A[(*t, *x)], A[True, False, 1, 1])) # True

You can also add full lists as well in the tuple:

print(np.allclose(A[(t, *x)], A[[True, False], 1, 1]))  # True

Python: slicing a multi-dimensional array

If you use numpy, this is easy:

slice = arr[:2,:2]

or if you want the 0's,

slice = arr[0:2,0:2]

You'll get the same result.

*note that slice is actually the name of a builtin-type. Generally, I would advise giving your object a different "name".


Another way, if you're working with lists of lists*:

slice = [arr[i][0:2] for i in range(0,2)]

(Note that the 0's here are unnecessary: [arr[i][:2] for i in range(2)] would also work.).

What I did here is that I take each desired row 1 at a time (arr[i]). I then slice the columns I want out of that row and add it to the list that I'm building.

If you naively try: arr[0:2] You get the first 2 rows which if you then slice again arr[0:2][0:2], you're just slicing the first two rows over again.

*This actually works for numpy arrays too, but it will be slow compared to the "native" solution I posted above.

Dimensions of array after multidimensional index slicing

https://docs.scipy.org/doc/numpy-1.15.4/reference/arrays.indexing.html#combining-advanced-and-basic-indexing

Your where masks will produce a 1d (7,) shape array if applied to a 2d array, the values where the condition is true. You phrase that as 'destroying' a pair of axes.

In the second case that 7 can be placed between the 2 and 5.

But in the first it's ambiguous because of the slice in the middle (the non adjacency) - the fall back rule is to put it first, and order the slices after. In other words, instead of trying to choose between a (2,7,4) and (2,4,7) order, it chooses (7,2,4).

The ambiguity is clear in this case, and the default reasonable. It's more complicated with one or more of the dimensions is eliminated by a scalar index.



Related Topics



Leave a reply



Submit