简体   繁体   English

如何使用 3d numpy 索引数组来检索 4d 数组中的相应值?

[英]How can I use a 3d numpy array of indices to retrieve the corresponding values i a 4d array?

I have a 4d numpy array temperature of data with the measured temperature at points x,y,z and time t.我有一个 4d numpy 数组temperature数据,在 x、y、z 点和时间 t 处测量温度。 Assuming I have an array indices with the indices where the first instance of a condition is met, say temperature < 0 , how do I extract a 3d array with the first temperatures satisfying this condition?假设我有一个数组indices ,其中包含满足条件的第一个实例的索引,例如temperature < 0 ,我如何提取满足此条件的第一个温度的 3d 数组? That is I'm looking for the equivalent of numpy's 1d version ( import numpy as np tacitly assumed)那就是我正在寻找相当于 numpy 的 1d 版本(默认import numpy as np

>>> temperatures = np.arange(10,-10,-1)
>>> ind = np.argmax(temperatures < 0)
>>> T = temperature[ind]

I have tried the analogous我试过类似的

In [1]: temperatures = np.random.random((11,8,5,200)) * 1000

In [2]: temperatures.shape
Out[2]: (11, 8, 5, 200)

In [3]: indices= np.argmax(temperatures > 900,axis=3)

In [4]: indices.shape
Out[4]: (11, 8, 5)

In [5]: T = temperatures[:,:,:,indices]

In [6]: T.shape
Out[6]: (11, 8, 5, 11, 8, 5)

However, the dimensions if T is 6.但是,如果T为 6,则尺寸。

I could of course do it with a for loop:我当然可以用 for 循环来做到这一点:

indices = np.argmax(temperatures > 900,axis=3)
x,y,z = temperatures.shape[:-1]
T = np.zeros((x,y,z))
for indx in range(x):
    for indy in range(y):
        for indz in range(z):
            T[indx,indy,indz] = temperatures[indx,indy,indz,indices[indx,indy,indz]]

but I'm looking for something fore elegant and more pythonic.但我正在寻找一些更优雅和更pythonic的东西。 Is there someone more skilled with numpy out there who can help me out on this?有没有更擅长 numpy 的人可以帮助我解决这个问题?

PS For the sake of clarity, I'm not just looking for the temperature at these points given by indices , I'm also looking for other quantities in arrays of the same shape as temperature , eg the time derivative. PS 为清楚起见,我不只是在寻找由indices给出的这些点处的温度,我还在寻找与temperature形状相同的数组中的其他量,例如时间导数。 Also, in reality the arrays are much larger then this minimal example.此外,实际上数组比这个最小的例子大得多。

Numpyadvanced indexing does always work: Numpy高级索引确实始终有效:

import numpy as np 
temperatures = np.random.random((11,8,5, 200)) * 1000
indices = np.argmax(temperatures > 900, axis=3)

x, y, z = temperatures.shape[:-1]

T = temperatures[np.arange(x)[:, np.newaxis, np.newaxis],
                 np.arange(y)[np.newaxis, :, np.newaxis],
                 np.arange(z)[np.newaxis, np.newaxis, :],
                 indices]

As jdehesa pointed out this can be made more concise:正如 jdehesa 指出的,这可以更简洁:

x, y, z = np.ogrid[:x, :y, :z]
T = temperatures[x, y, z, i]

I think you need:我认为你需要:

axis = 3
indices = np.argmax(temperatures > 900, axis=axis)
result = np.take_along_axis(temperatures, np.expand_dims(indices, axis), axis)
result = result.squeeze(axis)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM