2

Is there a 'pythonic' way to cleanly down-sample without multiple for loops?

This example below is the type of for loop I wish to get rid of.

Minimum working example:

import numpy as np
unsampled_array = [1,3,5,7,9,11,13,15,17,19]
number_of_samples = 7
downsampled_array = []
downsampling_indices = np.linspace(0, len(unsampled_array)-1, number_of_samples).round()
for index in downsampling_indices:
    downsampled_array.append(unsampled_array[int(index)])
print(downsampled_array)

Result:

>>> [ 1  5  7  9 13 17 19]
martineau
  • 119,623
  • 25
  • 170
  • 301
Jesse Reza Khorasanee
  • 3,140
  • 4
  • 36
  • 53

2 Answers2

3

If you want "real" downsampling, where each value is the mean of k values, you can use

unsampled_array.reshape(-1, k).mean(1) 

Make sure unsampled_array is a np.array. In your case, k=2. That will give you:

[ 2. 6. 10. 14. 18.]

* Update: If you just want to take the first item for each k items, you can use this code:

unsampled_array.reshape(-1, 2)[:, 0]

Take a look at this plot:

enter image description here

Noam Peled
  • 4,484
  • 5
  • 43
  • 48
  • You are correct. I didn't mention it in the question but I was initially interested in downsampling objects and downsampling between and to sample sizes. I guess I over simplified the example. – Jesse Reza Khorasanee Feb 25 '19 at 02:53
2

You need function np.ix_, as follows:

import numpy as np


unsampled_array = np.array([1,3,5,7,9,11,13,15,17,19])
number_of_samples = 5
downsampling_indices = np.linspace(0, len(unsampled_array)-1, number_of_samples).round()
downsampling_indices = np.array(downsampling_indices, dtype=np.int64)

indices = np.ix_(downsampling_indices)
downsampled_array = unsampled_array[indices]

print(downsampled_array)
Happy Boy
  • 526
  • 2
  • 9