iris.analysis.maths.mean?

435 views
Skip to first unread message

Paul Halloran

unread,
Dec 3, 2013, 3:11:03 PM12/3/13
to scitoo...@googlegroups.com
Hi All,

I've recently been making a lot of use of 'cube_out = iris.analysis.maths.divide/add/multiply/subtract(cube_a,cube_b)' etc. to look at differences/similarities between fields from different models.

It would be great to be able to do the same but mean the data - e.g.:

cube_out iris.analysis.maths.mean(cube_a,cube_b,cube_c)

but this is not an option. I know this can be got round easily, but the iris.analysis.maths... framework is nice and easy, does anyone know of a similar way to simply mean two separate cubes - there may well be something obvious that I'm missing...?

Thanks in advance,
Paul

Andrew Dawson

unread,
Dec 3, 2013, 4:06:52 PM12/3/13
to scitoo...@googlegroups.com
Currently what you are describing does not exist. However, you may not know that cubes override the basic maths operators to use iris.analysis.add etc., so you can use the normal operators with cubes and things just work. So to take the mean of three cubes you just need to do:

mean = (cube_a + cube_b + cube_c) / 3.

If this is too repetitive you could always write a simple wrapper:

def mean_cube(*cubes):
    n
= float(len(cubes))
   
return reduce(iris.analysis.maths.add, cubes) / n

which can be called with any number of cubes as the argument, for example:

mean = mean_cube(cube_a, cube_b, cube_c)

Have I addressed your question? I wasn't sure if that was what you meant...

Paul Halloran

unread,
Dec 5, 2013, 12:27:56 PM12/5/13
to scitoo...@googlegroups.com
Hi Andrew, that answers my question exactly, thank you very much.

The reduce function is also new to me, so that is really useful.

Thanks!
Paul

esc24

unread,
Dec 6, 2013, 11:04:52 AM12/6/13
to scitoo...@googlegroups.com
It's getting late on a friday afternoon, so I may be talking nonsense, but does scipy.mean([cube_a, cube_b, cube_b]) not work? Or even scipy.mean(cubelist)?

Stephan Hoyer

unread,
Dec 7, 2013, 12:35:07 AM12/7/13
to scitoo...@googlegroups.com
You can't use scipy.mean (or np.mean, which is actually what scipy.mean calls under the covers), because it expects the arguments to be numpy arrays.

However, you can use Python's built-in "sum", which works on any data type, since sum([a,b,c]) is effectively expanded to a+b+c.

So my preferred solution is actually:

def mean(*args):
   
return sum(args) / float(len(args))

You can call this mean function on any arguments, whether they are numpy arrays or cube or whatever.

Cheers,
Stephan

Andrew Dawson

unread,
Dec 7, 2013, 9:18:44 AM12/7/13
to scitoo...@googlegroups.com
It's getting late on a friday afternoon, so I may be talking nonsense, but does scipy.mean([cube_a, cube_b, cube_b]) not work? Or even scipy.mean(cubelist)?

Actually I think you are right, something like numpy.mean(cubelist) seems to work absolutely fine.

You can't use scipy.mean (or np.mean, which is actually what scipy.mean calls under the covers), because it expects the arguments to be numpy arrays.

It does work because the input list/cubelist will be turned into a numpy array where each element is a cube. 

Stephan Hoyer

unread,
Dec 7, 2013, 5:55:42 PM12/7/13
to scitoo...@googlegroups.com
Here's what I get when I tried this:

>>> print np.mean(cubes)

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-255-b689c50cf263> in <module>()
----> 1 print np.mean(cubes)


/Users/shoyer/dev/climatology-research/library/python/target/climatology/lib/python2.7/site-packages/numpy/core/fromnumeric.pyc in mean(a, axis, dtype, out, keepdims)
   
2714
   
2715     return _methods._mean(a, axis=axis, dtype=dtype,
-> 2716                             out=out, keepdims=keepdims)
   
2717
   
2718 def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):


/Users/shoyer/dev/climatology-research/library/python/target/climatology/lib/python2.7/site-packages/numpy/core/_methods.pyc in _mean(a, axis, dtype, out, keepdims)
     
65                 ret, rcount, out=ret, casting='unsafe', subok=False)
     
66     else:
---> 67         ret = ret.dtype.type(ret / rcount)
     
68
     
69     return ret


AttributeError: 'Cube' object has no attribute 'dtype'


> /Users/shoyer/dev/climatology-research/library/python/target/climatology/lib/python2.7/site-packages/numpy/core/_methods.py(67)_mean()
     
66     else:
---> 67         ret = ret.dtype.type(ret / rcount)
     
68


>>> print np.sum(cubes)
unknown
/ (Celsius)                 (time: 23351; station: 3)
     
Dimension coordinates:
          time                           x              
-
          station                        
-               x
     
Auxiliary coordinates:
          latitude                      
-               x
          longitude                      
-               x
          station_id                    
-               x

So bizarrely, it appears that np.sum works but np.mean doesn't.

Andrew Dawson

unread,
Dec 8, 2013, 4:26:38 AM12/8/13
to scitoo...@googlegroups.com
That is odd because this example works for me:

import numpy as np
import numpy.ma as ma
import iris


a1
= ma.array([[1., 2., 3.], [4., 5., 6.]], mask=[[0, 1, 0], [0, 0, 1]])
a2
= ma.array([[8., 2., 1.], [3., 1., 4.]], mask=[[0, 1, 0], [0, 0, 1]])
print 'desired solution:'
print '-----------------'
print (a1 + a2) / 2.

print
print 'now with cubes'
print '--------------'
c1
= iris.cube.Cube(a1)
c2
= iris.cube.Cube(a2)
cs
= np.mean([c1, c2])
print c1
print c2
print cs
print cs.data

It also works with a CubeList. I'm using numpy 1.7.1.

Stephan Hoyer

unread,
Dec 9, 2013, 12:09:52 AM12/9/13
to scitoo...@googlegroups.com
I'm running NumPy 1.8.0 (and the dev version of Iris), so that could very well explain why it doesn't work for me. I agree that this is very bizarre!

Cheers,
Stephan

Andrew Dawson

unread,
Dec 9, 2013, 2:35:01 AM12/9/13
to scitoo...@googlegroups.com

Well I guess that means it isn't a good idea then! It seems like writing a wrapper around the built-in sum function might be the best choice here.

--
You received this message because you are subscribed to the Google Groups "Iris" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scitools-iri...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
Reply all
Reply to author
Forward
0 new messages