81

Given two ndarrays

old_set = [[0, 1], [4, 5]]
new_set = [[2, 7], [0, 1]]

I'm looking to get the mean of the respective values between the two arrays so that the data ends up something like:

end_data = [[1, 4], [2, 3]]

basically it would apply something like

for i in len(old_set):
    end_data[i] = (old_set[i]+new_set[i])/2

But I'm unsure what syntax to use.. Thanks for the help in advance!

Forde
  • 863
  • 1
  • 7
  • 9

4 Answers4

177

You can create a 3D array containing your 2D arrays to be averaged, then average along axis=0 using np.mean or np.average (the latter allows for weighted averages):

np.mean( np.array([ old_set, new_set ]), axis=0 )

This averaging scheme can be applied to any (n)-dimensional array, because the created (n+1)-dimensional array will always contain the original arrays to be averaged along its axis=0.

Saullo G. P. Castro
  • 56,802
  • 26
  • 179
  • 234
  • 4
    Excellent use of numpy functions. – KLDavenport Jan 19 '15 at 03:30
  • 3
    I really like this option. Specially, if you want to ignore nan: `np.nanmean( np.array([ old_set, new_set ]), axis=0 )` – Sina Oct 13 '15 at 07:51
  • 6
    You can also extend this to an arbitrary number of arrays using `np.mean( np.array([ i for i in bigArr]), axis=0 )` where `bigArr` is composed of many one 1D arrays to average. – Ianhi Jul 15 '16 at 15:22
  • 1
    This should be the accepted answer as it supports an arbitrary number of arrays, too. – Roman May 01 '20 at 20:15
52
>>> import numpy as np
>>> old_set = [[0, 1], [4, 5]]
>>> new_set = [[2, 7], [0, 1]]
>>> (np.array(old_set) + np.array(new_set)) / 2.0
array([[1., 4.],
       [2., 3.]])
falsetru
  • 357,413
  • 63
  • 732
  • 636
  • 15
    Unless you are using Python 3 or you use `from __future__ import division`, you should divide by 2.0 to ensure that you use true division and not integer division. – Warren Weckesser Aug 27 '13 at 12:29
  • obviously, if both are already np.arrays, `(old_set + new_set) / 2` will suffice. just ask `type(old_set),type(new_set)` to remind yourself what you are dealing with. – Gabriel123 May 18 '20 at 08:44
  • @Gabriel123, According to the code in question, they are lists, unlike OP mentioned. ;) – falsetru May 18 '20 at 08:56
5

Using numpy.average

Also numpy.average can be used with the same syntax:

import numpy as np
a = np.array([np.arange(0,9).reshape(3,3),np.arange(9,18).reshape(3,3)])
averaged_array = np.average(a,axis=0)

The advantage of numpy.average compared to numpy.mean is the possibility to use also the weights parameter as an array of the same shape:

weighta = np.empty((3,3))    
weightb = np.empty((3,3))       
weights = np.array([weighta.fill(0.5),weightb.fill(0.8) ])
np.average(a,axis=0,weights=weights)

If you use masked arrays consider also using numpy.ma.average because numpy.average don't deal with them.

Community
  • 1
  • 1
G M
  • 20,759
  • 10
  • 81
  • 84
0

As previously said, your solution does not work because of the nested lists (2D matrix). Staying away from numpy methods, and if you want to use nested for-loops, you can try something like:

old_set = [[0, 1], [4, 5]]
new_set = [[2, 7], [0, 1]]

ave_set = []
for i in range(len(old_set)):
    row = []
    for j in range(len(old_set[0])):
        row.append( ( old_set[i][j] + new_set[i][j] ) / 2 )
    ave_set.append(row)
print(ave_set) # returns [[1, 4], [2, 3]]
Gabriel123
  • 426
  • 5
  • 11