1

I have a list (called ys) of three lists (ys[0], ys[1], ys[2]). Each of the three lists contains 10 arrays each of length 1534. The first list is shown below for example:

In [57]: print ys[0]
[array([ 1655.13816505,  1547.98589715,   572.2745519 , ...,    89.10781318,
      93.89836665,    95.07931966]), array([ 1222.2549591 ,   375.13612313,  1117.62684517, ...,    92.01444874,
      96.37158146,    98.09804547]), array([ 405.61715294,  347.45411   ,  458.31631866, ...,   95.87440348,
     92.59379305,   96.88934008]), array([  958.5300296 ,   690.68863703,  1315.69537196, ...,    96.02464434,
      94.58280479,    93.77347022]), array([ 276.97463055,  457.34617477,  908.78859867, ...,   94.75916652,
     94.02373941,   94.15538106]), array([ 1822.50632297,   596.38771818,  1163.05119636, ...,    90.92428715,
      97.46551579,    90.34230747]), array([ 1609.11576638,  1343.19751488,   891.16993616, ...,    94.081789  ,
      91.84201144,    94.06961381]), array([ 1481.02653876,   843.39342494,  1208.37885821, ...,    95.86349883,
      95.93122661,    92.94565202]), array([ 1330.1940189 ,   844.70910408,  1151.75233836, ...,    98.82465514,
     100.37876234,    96.15178672]), array([ 1287.56325832,   365.89812057,  1034.15108853, ...,    90.64446465,
      94.99436954,    90.88272168])]

I would like to find a way to sum these arrays element by element so that I am left with one array of length 1534. The excerpt from the code that generates the list of three lists is this:

def ys(norm2, ell_T):
    t=[]
    e=[]
    b=[]
    T=norm2[0]
    E=norm2[1]
    B=norm2[2]
    for i in range (0, len(T)):
        yt=((ell_T * (ell_T+1) * T[i])/(2*pi))
        ye=((ell_T * (ell_T+1) * E[i])/(2*pi))
        yb=((ell_T * (ell_T+1) * B[i])/(2*pi))
        t.append(yt)
        e.append(ye)
        b.append(yb)
    return t, e, b

ys=ys(norm2, ell_T)

My attempt at the summation and a subsequent average (which doesn't work) is shown below:

def averageys(ys, theory):
    t=[]
    e=[]
    b=[]
    for i in range(1, len(ys[0])):
        yst_arrays=ys[0][i]
        yse_arrays=ys[1][i]
        ysb_arrays=ys[2][i]
        sumT=np.add(yst_arrays)
        sumE=np.add(yse_arrays)
        sumB=np.add(ysb_arrays)
        avt=sumT/len(ys[0])
        ave=sumE/len(ys[0])
        avb=sumB/len(ys[0])
        t.append(avt)
        e.append(ave)
        b.append(avb)
    return t, e, b

averageys=averageys(ys, theory)

The problem seems to be the np.add functions. They require inputs such as np.add(ys[0][0], ys[0][1], etc...) but I want to generalise this so it isn't fixed to 10 arrays.

1
  • Your final result will be three arrays of 1534 elements each? Commented Dec 12, 2014 at 1:22

5 Answers 5

2

If I correctly understand, you want to sum the arrays in e.g. ys[0] together? Thus, I made a dummy example, hopfully simulating your case

import numpy as np

ys = [[np.array([1,1,1]), np.array([1,1,1])]*5,   # 10 array of length 3 instead 1534
      [np.array([2, 2,2]), np.array([2,2,2])]*5,  # 10 array of length 3 instead 1534
      [np.array([3, 3,3]), np.array([3,3,3])]*5]  # 10 array of length 3 instead 1534 

Thus, you can sum them simply by:

print(list(map(sum, ys)))

This results in:

[array([10, 10, 10]), array([20, 20, 20]), array([30, 30, 30])]

And if you want to sum all of them:

print(sum(list(map(sum, ys))))
# gives: [60 60 60]
Sign up to request clarification or add additional context in comments.

Comments

2

Have you tried converting your list (y) of lists of numpy arrays to one single numpy array and then summing over one of the axes? Working with numpy arrays has a lot of advantages over normal python constructs (lists and all kinds of list comprehensions or functional constructs such as map) when you're working with (a lot of) numerical data.

As your code isn't a minimal working example, I'll use a different example with less arrays:

>>> f0 = [np.random.random_integers(0, 10, (3,)) for _ in range(2)]    
>>> f1 = [np.random.random_integers(0, 10, (3,)) for _ in range(2)]    
>>> f2 = [np.random.random_integers(0, 10, (3,)) for _ in range(2)]    
>>> y = [f0, f1, f2]    
>>> y 
[[array([7, 8, 3]), array([ 7, 10,  0])],
 [array([2, 7, 8]), array([2, 6, 7])],
 [array([3, 5, 0]), array([7, 3, 6])]]
>>> y[0]  # it's a list of 2 numpy arrays, similar to your example
[array([7, 8, 3]), array([ 7, 10,  0])]
>>> arr = np.array(y)  # conversion of list of lists of arrays to one numpy array
>>> arr  # it is now an array with 3 axes. Its shape is (3, 2, 3)
array([[[ 7,  8,  3],
        [ 7, 10,  0]],

       [[ 2,  7,  8],
        [ 2,  6,  7]],

       [[ 3,  5,  0],
        [ 7,  3,  6]]])

To sum only the arrays present within f0, f1 and f2, you could:

>>> arr.sum(axis=1) 
array([[14, 18,  3],
       [ 4, 13, 15],
       [10,  8,  6]])

To sum over f0, f1 and f2 (all together), you could take the sum of the previous array over axis=0 or

>>> f = arr.reshape(3*2, 3); f 
array([[ 7,  8,  3],
       [ 7, 10,  0],
       [ 2,  7,  8],
       [ 2,  6,  7],
       [ 3,  5,  0],
       [ 7,  3,  6]])

>>> f.sum(axis=0)  # take the sum over all rows
array([28, 39, 24])

Once you've summed all these, you could calculate the mean by dividing by the number of rows you've summed. For the first scenario (taking the sum only over f0, f1 and f2 separately), you could even just say arr.mean(axis=1), which will give you:

>>> arr.mean(axis=1)
array([[ 7. ,  9. ,  1.5],
       [ 2. ,  6.5,  7.5],
       [ 5. ,  4. ,  3. ]])

Which you can easily verify by hand from the example above.

1 Comment

Hi @JKM if this or any answer has solved your question please consider accepting it by clicking the check-mark. This indicates to the wider community that you've found a solution and gives some reputation to both the answerer and yourself. There is no obligation to do this though.
1

You can sum up the individual arrays step at a time:

# Sums up the 10 arrays in each of the 3 lists
reduced_ys = [[sum(value) for value in zip(*ys_list)] for ys_list in zip(*ys)]

# Sums up the 3 remaining lists
final_ys = [sum(ys_list) for ys_list in zip(*reduced_ys)]

The syntax here can also be seen in the question Merging/adding lists in Python.

Comments

0

Here's your solution.

def averageys(ys):
    return list(map(sum, (list(map(sum, ys)))))

Comments

0

If you just want to generalize and fix your function:

def averageys(ys, theory):
    # seperate the three groups of data
    yst, yse, ysb = ys

    # number of items in the sum
    # assumes len(yst)==len(yse)==len(ysb)
    # n needs to be a float for the mean to work
    n = float(len(yst))

    # element-wise sum of each item in the sublists
    # the * operator preceding the argument will unpack each item in the sublist
    sumT=np.add(*yst)
    sumE=np.add(*yse)
    sumB=np.add(*ysb)

    avt=sumT/n
    ave=sumE/n
    avb=sumB/n
    return avt, ave, avb

BUT: see Oliver W.'s answer for the correct way to do this.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.