Python Series Sum Resample

Viewed 111

Given a list [5,2,4,5,1,2,4,5], how to do a sum resample like pandas.resample df.resample().sum() without the hasle of creating a DatetimeIndex?

inp = [5,2,4,5,1,2,4,5]
out = resample(inp, 2, how='sum')

>> [7, 9, 3, 9]

Note: This is because df.resample().sum() only accept datetime-like index. I have spent some time googling this topic but find nothing. Sorry if there is exist a same question like this.

Edit:

A manual solution might look like this

import numpy as np

def resample_sum(inp, window):
    return np.sum(np.reshape(inp, (len(inp)//window, window)), axis=1)
1 Answers
def resample(inp_list,window_size,how='sum'):
    output = []
    for i in range(0,len(inp_list),window_size):
        window = inp_list[i:i+window_size]
        if how == 'sum':
           output.append(sum(window))
        else:
            raise NotImplementedError #replace this with other how's you want
    return output
            
inp = [5,2,4,5,1,2,4,5]
out = resample(inp, 2, how='sum')
#[7, 9, 3, 9]

Edit 1: A vectorized numpy array solution which will have better performance for a huge array. The idea is to reshape the array into a 2-d array where the rows of the new array are the values that should be summed together.

import numpy as np
def resample(inp_array,window_size,how='sum'):
    inp_array = np.asarray(inp_array)

    #check how many zeros need to be added to the end to make
    #   the array length a multiple of window_size 
    pad = (window_size-(inp_array.size % window_size)) % window_size
    if pad > 0:
        inp_array = np.r_[np.ndarray.flatten(inp_array),np.zeros(pad)]
    else:
        inp_array = np.ndarray.flatten(inp_array)

    #reshape so that the number of columns = window_size
    inp_windows = inp_array.reshape((inp_array.size//window_size,window_size))
    
    if how == 'sum':
       #sum across columns
       return np.sum(inp_windows,axis=1)
    else:
       raise NotImplementedError #replace this with other how's you want

inp = [5,2,4,5,1,2,4,5]
out = resample(inp, 2, how='sum')
#[7, 9, 3, 9]

Edit 2: The closest thing to this I found in a popular library is skimage.measure.block_reduce.

You can treat your data as a 1-dimensional image, pass a block size, and pass the np.sum function.

Related