Louis T
Louis T

Reputation: 75

How to resample an array by duplicating/skipping every N item?

I am confused on how to achieve the following:

Say I have an array of size X (e.g: 3000 items). I want to create a function that will stretch that array to size Y (e.g: 4000) by duplicating every N item. Along with another function to do the opposite, remove every N items to make the array size 2000 for example.

I guess this is more of a math problem than a programming problem, and as you can tell maths aren't my strong point. Here's what I have so far:

def upsample(originalArray, targetSize):
    newArray = []
    j = 0
    for i in range (0, len(originalArray)):
        newArray.append(originalArray[i])

        # calculate at what interval items need to be duplicated
        # this is what I'm having trouble with

        if j == interval:
            newArray.append(originalArray[i])
            j = 0

        j+=1

    return newArray

Here is an example of what I'm trying to do:

# stretch array from 10 to 12 items
originalArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
upsample(originalArray, 11)
# output: [0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9]

Any help will be much appreciated

Upvotes: 2

Views: 238

Answers (2)

roschach
roschach

Reputation: 9336

To downsample your array:

N =2 #downsampling by 2
new = originalArray[0:N:]

To upsample (a being originaArray):

new = [item  for t in [[a[i]]*2 if i%N==0 else [a[i],] for i in range(0,len(a))] for item in t]

or more explicitly:

res = list()
i=0
while(i<len(originalArray)):
     res.append(originalArray[i])
     if i%N==0:
         continue
     i +=1

Upvotes: 1

Jonas
Jonas

Reputation: 1847

Create a floating point linspace and map it back to integer to use it as indices for your original Array. (Since you wanted [0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9] instead of [0, 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9] you need to do this flipping stuff in the if condition).

The code avoids loops for performance.

import numpy as np
def upsample(originalArray, targetSize):
    x = np.linspace(0, originalArray.size, num=targetSize, endpoint=False)
    if targetSize > originalArray.size:
        x = -np.flip(x, axis=0) + originalArray.size
        x[-1] = originalArray.size - 1
    x = originalArray[x.astype(int)]
    return x

upsample(originalArray, 21) gives [0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 9]

upsample(originalArray, 23) gives [0 0 1 1 2 2 3 3 3 4 4 5 5 6 6 6 7 7 8 8 9 9 9]

upsample(originalArray, 5) gives [0 2 4 6 8]

etc.

Upvotes: 1

Related Questions