numo-narray icon indicating copy to clipboard operation
numo-narray copied to clipboard

Way to get a range of sub-arrays similar to numpy's `x[a:b]`

Open jneen opened this issue 1 year ago • 4 comments

Hey there! Thanks for this software.

I'm attempting to do some audio processing, which involves a lot of splitting a big 2d array into smaller chunks. My wave is of shape [big_number, 2], for 2-channel stereo audio, and I'm attempting to slice this to get a time range. I would expect, for example, wave[0...1024] to result in an array of shape [1024, 2], but it seems to treat the whole thing as flat and just return an array of shape [1024].

I had a search through the docs and examples and couldn't find anything like this - is there a way to take this kind of slice or do i have to math out the size and reshape afterwards?

jneen avatar Jun 18 '24 15:06 jneen

Concrete example:

[10] pry(Spectrum)> @samples
=> Numo::SFloat#shape=[6513231,2]
[[0, 3.05185e-05], 
 [3.05185e-05, 6.1037e-05], 
 [6.1037e-05, 6.1037e-05], 
 [3.05185e-05, 0], 
 [0, -3.05185e-05], 
 [0, -3.05185e-05], 
 [0, -3.05185e-05], 
 [0, 0], 
 [3.05185e-05, 3.05185e-05], 
 [6.1037e-05, 3.05185e-05], 
 [9.15555e-05, 3.05185e-05], 
 [6.1037e-05, 3.05185e-05], 
 [-6.1037e-05, -6.1037e-05], 
 [-0.000152593, -9.15555e-05], 
 [-0.000152593, -9.15555e-05], 
 [-0.000122074, -6.1037e-05], 
 [0, 3.05185e-05], 
 [6.1037e-05, 3.05185e-05], 
 [0, -0.000152593], 
 [-3.05185e-05, -0.000244148], 
 ...
[11] pry(Spectrum)> @samples[0...1024]
=> Numo::SFloat(view)#shape=[1024]
[0, 3.05185e-05, 3.05185e-05, 6.1037e-05, 6.1037e-05, 6.1037e-05, ...]

jneen avatar Jun 18 '24 15:06 jneen

I think the thing I would want (and how normal ruby arrays work) is more similar to this:

[4] pry(Spectrum)> @samples[0...2048].reshape(1024, 2)
=> Numo::SFloat#shape=[1024,2]
[[0, 3.05185e-05], 
 [3.05185e-05, 6.1037e-05], 
 [6.1037e-05, 6.1037e-05], 
 [3.05185e-05, 0], 
 [0, -3.05185e-05], 
 [0, -3.05185e-05], 
 [0, -3.05185e-05], 
 [0, 0], 
 [3.05185e-05, 3.05185e-05], 
 [6.1037e-05, 3.05185e-05], 
 [9.15555e-05, 3.05185e-05], 
 [6.1037e-05, 3.05185e-05], 
 [-6.1037e-05, -6.1037e-05], 
 [-0.000152593, -9.15555e-05], 
 [-0.000152593, -9.15555e-05], 
 [-0.000122074, -6.1037e-05], 
 [0, 3.05185e-05], 
 [6.1037e-05, 3.05185e-05], 
 [0, -0.000152593], 
 [-3.05185e-05, -0.000244148], 
 ...

But this feels like it leaks the abstraction of shapes a little bit and forces me to think of it as a totally flattened array.

jneen avatar Jun 18 '24 15:06 jneen

Hi @jneen I'm not very familiar with NumPy, so I don't know if my answer is what you expect, but I think you can use true.

import numpy as np

x = np.array([[1, 2, 3, 4],
              [5, 6, 7, 8],
              [9, 10, 11, 12]])

x[1:3]
# array([[ 5,  6,  7,  8],
#       [ 9, 10, 11, 12]])
require 'numo/narray'

x = Numo::Int32[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
]

x[1...3, true]
# x[1..2, true]

# Numo::Int32(view)#shape=[2,4]
# [[5, 6, 7, 8], 
#  [9, 10, 11, 12]]

I'm glad you're interested in NArray.

kojix2 avatar Jun 19 '24 01:06 kojix2

Oh! That's... certainly an interesting way to do it. Thanks!

jneen avatar Jun 19 '24 04:06 jneen