2

У меня есть экспериментальные наблюдения в объеме:Функции для вычисления 3D градиента с неравноотстоящими местами образца

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 

Это дает мне ошибку:

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

EDIT: В соответствии с @ сойкой-kominek в комментарии:

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

Я обновил вопрос. Есть ли какая-либо функция, которая может выполнять мои вычисления?

+0

Просто увидел, что ось у не линейно разнесены. Возможно, вам придется интерполировать это на линейной сетке. – roadrunner66

+0

Обратите внимание, что 'linspace' страдает ошибкой fencepost относительно' np.arange', поэтому для получения 0,1 разницы вам нужны 11, 9, 5 'posts'. – roadrunner66

+0

Я обновил вопрос и заголовок, чтобы было ясно, что интервалы неравномерны. – crypdick

ответ

0

Необходимые dx ... для передачи np.gradient не являются сетками различий, а всего лишь одним скаляром. Так выглядит grad = np.gradient(tt,0.1,0.1,0.1).

+0

Все еще дает ту же ошибку. –

+0

Это работает для меня, но я получаю неизменный результат, когда аналитическое решение должно быть [2x, 2y, 2z]. – roadrunner66

+0

К сожалению, я ошибся 'x * 2' за' x ** 2', он работает. – roadrunner66

3

Две вещи, которые следует обратить внимание: во-первых, скаляры - это одиночные значения, а не массивы. Во-вторых, сигналом функции является numpy.gradient(f, *varargs, **kwargs). Обратите внимание на * до varargs. Это означает, что если varargs есть список, вы проходите *varargs. Или вы можете просто предоставить элементы varargs в качестве отдельных аргументов.

Так, np.gradient хочет одно значение для расстояния по каждому измерению, как:

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

или:

distances = [np.diff(x)[0], np.diff(y)[0], np.diff(z)[0]] 
np.gradient(tt, *distances) 
+0

Ницца, чистое объяснение. – roadrunner66

+0

или просто '(x [1] - x [0]), (y [1] - y [0]), (z [1] - z [0])', чтобы избежать вычисления избыточных различий, когда 'x' большой. –

+0

Привет, Джей, этот ответ, поскольку он стоит, предполагает, что различия постоянны. Я обновил вопрос и пример, чтобы было ясно, что данные неравномерно отобраны. – crypdick

Смежные вопросы