Edit function to work for arrays instead of lists

Question:

I have a function that does the following:

  1. Takes uses the list as an input
  2. Computes the sum of the list
  3. Appends the output (the sum) to the input list
  4. Runs itself again (this time with a list of N + 1 data).

I want to to do this exact thing for an input of a numpy array, but I don’t get a complete solution.

This is what I currently have:

data = [15.5, 19.2, 27.8, 44.6, 71.0, 54.1, 60.2]


def AppendOutput(data, steps):
    
    for i in range(steps):
        s = sum(data)
        emp.append(s)
        data.append(emp)
    return data


s = AppendOutput(data, 3)

This outputs the following, which is what I want:

[15.5, 19.2, 27.8, 44.6, 71.0, 54.1, 60.2, 292.4, 584.8, 1169.6]

My current issue is that I’m trying to accomplish the same thing for an input that is a numpy array.

data_array = np.array([data])

def AppendOutputNP(data, steps):
    for j in range(steps):
        temp = np.sum(data_array).reshape((-1,1))
        new = np.append(data_array, temp, axis=1)
    return new

AppendOutputNP(data_array, 3)

I get a partial solution in comparison to what I would get for the original function; this time only one element gets appended instead of three:

array([[ 15.5,  19.2,  27.8,  44.6,  71. ,  54.1,  60.2, 292.4]])

Could anyone direct me as to what I’m doing wrong here?

Asked By: Volti

||

Answers:

It’s probably best to form the result array at the start of the function. numpy.append is quite slow.

def AppendSumNP(data, steps, dtype = np.float64 ):
    result = np.zeros( len(data) + steps, dtype = dtype ) 
    # The result array is big enough for the whole result
    result[ :len(data) ] = data
    for j in range( len(data), len(data) + steps ):
        result[ j ] = result[:j].sum()
    return result

Also the second sum is twice the first and the third twice the second, etc. so only sum once, then multiply.

def AppendMultNP(data, steps, dtype = np.float64 ):
    result = np.zeros( len(data) + steps, dtype = dtype )
    result[ :len(data)] = data
    total = result[:len(data)].sum()
    for j in range( len(data), len(data) + steps ):
        result[ j ] = total
        total *= 2
    return result

It depends how long the data list is but the Mult approach can be several times as fast.

Answered By: Tls Chris
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.