4

I have experimental observations in a volume:

import numpy as np

# observations are not uniformly spaced 
x = np.random.normal(0, 1, 10)
y = np.random.normal(5, 2, 10)
z = np.random.normal(10, 3, 10)
xx, yy, zz = np.meshgrid(x, y, z, indexing='ij')

# fake temperatures at those coords
tt = xx*2 + yy*2 + zz*2

# sample distances
dx = np.diff(x)
dy = np.diff(y)
dz = np.diff(z)

grad = np.gradient(tt, [dx, dy, dz])  # returns error

This gives me the error:

ValueError: operands could not be broadcast together with shapes (10,10,10) (3,9) (10,10,10).

EDIT: according to @jay-kominek in the comments below:

np.gradient won't work for you, it simply doesn't handle unevenly sampled data.

I've updated the question. Is there any function which can can do my computation?

crypdick
  • 16,152
  • 7
  • 51
  • 74

2 Answers2

3

Two things to note: First, scalars are single values, not arrays. Second, the signature of the function is numpy.gradient(f, *varargs, **kwargs). Note the * before varargs. That means if varargs is a list, you pass *varargs. Or you can just provide the elements of varargs as separate arguments.

So, np.gradient wants a single value for the distance along each dimension, like:

np.gradient(tt, np.diff(x)[0], np.diff(y)[0], np.diff(z)[0])

or:

distances = [np.diff(x)[0], np.diff(y)[0], np.diff(z)[0]]
np.gradient(tt, *distances)
Jay Kominek
  • 8,674
  • 1
  • 34
  • 51
  • Nice, clean explanation. – roadrunner66 Apr 22 '16 at 00:08
  • or just `(x[1] - x[0]), (y[1] - y[0]), (z[1] - z[0])` to avoid calculating redundant differences when `x` is large. – Imanol Luengo Apr 22 '16 at 11:06
  • Hi Jay, this answer as it stands assums the diffs are constant. I updated the question and example to make it clear that the data is unevenly sampled. – crypdick Apr 26 '16 at 17:49
  • 1
    @RovingRichard `np.gradient` won't work for you, it simply doesn't handle unevenly sampled data. https://github.com/numpy/numpy/blob/master/numpy/lib/function_base.py#L1380 – Jay Kominek Apr 26 '16 at 18:39
0

The required dx ... to be passed to np.gradient aren't grids of differences, but just one scalar each. So grad = np.gradient(tt,0.1,0.1,0.1)appears to work.

roadrunner66
  • 7,772
  • 4
  • 32
  • 38