Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 基于最小/最大值的Numpy动态数组切片_Python_Arrays_Numpy - Fatal编程技术网

Python 基于最小/最大值的Numpy动态数组切片

Python 基于最小/最大值的Numpy动态数组切片,python,arrays,numpy,Python,Arrays,Numpy,我有一个三维hape(365,x,y)数组,其中36对应于=每日数据。在某些情况下,沿时间轴轴=0的所有元素都是np.nan 沿轴=0的每个点的时间序列如下所示: early_minimum_indexes = np.full_like(peak_indexes, fill_value=0) for i in range(peak_indexes.shape[0]): for j in range(peak_indexes.shape[1]): if peak_inde

我有一个三维hape
(365,x,y
)数组,其中36对应于=每日数据。在某些情况下,沿时间轴
轴=0
的所有元素都是
np.nan

沿
轴=0的每个点的时间序列如下所示:

early_minimum_indexes = np.full_like(peak_indexes, fill_value=0)

for i in range(peak_indexes.shape[0]):
    for j in range(peak_indexes.shape[1]):
        if peak_indexes[i, j] == 0:
            early_minimum_indexes[i, j] = 0
        else:
            early_mask = np.ma.masked_array(a, np.isnan(a))
            early_loc = np.nanargmin(early_mask[:peak_indexes[i, j], i, j], axis=0)   
            early_minimum_indexes[i, j] = early_loc
peak_index = np.nanargmax(a1)
mask = np.zeros(a1.size, dtype=np.bool)
mask[peak:] = True
trough_plus = np.nanargmin(np.ma.array(a1, mask=~mask))
trough_minus = np.nanargmin(np.ma.array(a1, mask=mask))

我需要找到最大值(峰值数据)出现的索引,然后是峰值每一侧的两个最小值

import numpy as np

a = np.random.random(365, 3, 3) * 10
a[:, 0, 0] = np.nan

peak_mask = np.ma.masked_array(a, np.isnan(a))
peak_indexes = np.nanargmax(peak_mask, axis=0)
我可以使用以下方法找到峰值前的最小值:

early_minimum_indexes = np.full_like(peak_indexes, fill_value=0)

for i in range(peak_indexes.shape[0]):
    for j in range(peak_indexes.shape[1]):
        if peak_indexes[i, j] == 0:
            early_minimum_indexes[i, j] = 0
        else:
            early_mask = np.ma.masked_array(a, np.isnan(a))
            early_loc = np.nanargmin(early_mask[:peak_indexes[i, j], i, j], axis=0)   
            early_minimum_indexes[i, j] = early_loc
peak_index = np.nanargmax(a1)
mask = np.zeros(a1.size, dtype=np.bool)
mask[peak:] = True
trough_plus = np.nanargmin(np.ma.array(a1, mask=~mask))
trough_minus = np.nanargmin(np.ma.array(a1, mask=mask))
得出的峰值和谷值如下所示:

early_minimum_indexes = np.full_like(peak_indexes, fill_value=0)

for i in range(peak_indexes.shape[0]):
    for j in range(peak_indexes.shape[1]):
        if peak_indexes[i, j] == 0:
            early_minimum_indexes[i, j] = 0
        else:
            early_mask = np.ma.masked_array(a, np.isnan(a))
            early_loc = np.nanargmin(early_mask[:peak_indexes[i, j], i, j], axis=0)   
            early_minimum_indexes[i, j] = early_loc
peak_index = np.nanargmax(a1)
mask = np.zeros(a1.size, dtype=np.bool)
mask[peak:] = True
trough_plus = np.nanargmin(np.ma.array(a1, mask=~mask))
trough_minus = np.nanargmin(np.ma.array(a1, mask=mask))

对于大型阵列(1m+单元),这种方法在时间上是非常不合理的。使用numpy有更好的方法吗?

这里有一个方法

  • 复制数据
  • 保存所有nan位置并将所有nan替换为全局min-1
  • 查找按行argmax
  • 从整行中减去其值
    • 请注意,现在每行只有非正值,最大值为零
  • 将所有位置置零
  • 将所有值的符号翻转到最大值的右侧
    • 这是主要思想;它在之前存在右手最小值的位置创建一个新行全局最大值;同时,它确保左手边的min现在是row全局的
  • 检索按行排列的argmin和argmax,这是原始数组中左分钟和右分钟的位置
  • 查找所有nan行,并用INVALINT覆盖这些位置的最大和最小索引
  • 代码:


    虽然在这种情况下使用遮罩阵列可能不是最有效的解决方案,但它将允许您在特定轴上执行遮罩操作,同时或多或少保留形状,这是一种极大的方便。请记住,在许多情况下,屏蔽函数仍然会复制屏蔽数据

    在您当前的代码中,您的想法基本正确,但是您错过了一些技巧,比如能够否定和组合掩码。另外,将掩码预先分配为布尔值更为有效,并且有一些小问题,如
    np.full(…,0)->np.zeros(…,dtype=bool)

    让我们把这个倒过来。假设您有一个性能良好的具有峰值的一维数组,比如说
    a1
    。您可以使用掩蔽来轻松找到最大值和最小值(或指数),如下所示:

    early_minimum_indexes = np.full_like(peak_indexes, fill_value=0)
    
    for i in range(peak_indexes.shape[0]):
        for j in range(peak_indexes.shape[1]):
            if peak_indexes[i, j] == 0:
                early_minimum_indexes[i, j] = 0
            else:
                early_mask = np.ma.masked_array(a, np.isnan(a))
                early_loc = np.nanargmin(early_mask[:peak_indexes[i, j], i, j], axis=0)   
                early_minimum_indexes[i, j] = early_loc
    
    peak_index = np.nanargmax(a1)
    mask = np.zeros(a1.size, dtype=np.bool)
    mask[peak:] = True
    trough_plus = np.nanargmin(np.ma.array(a1, mask=~mask))
    trough_minus = np.nanargmin(np.ma.array(a1, mask=mask))
    
    这尊重这样一个事实,即遮罩数组相对于普通numpy布尔索引翻转遮罩的意义。最大值出现在
    槽加上的计算中也可以,因为它保证不是最小值(除非您有所有nan情况)

    现在,如果
    a1
    已经是一个掩码数组(但仍然是1D),则可以执行相同的操作,但暂时合并掩码。例如:

    a1 = np.ma.array(a1, mask=np.isnan(a1))
    peak_index = a1.argmax()
    mask = np.zeros(a1.size, dtype=np.bool)
    mask[peak:] = True
    trough_plus = np.ma.masked_array(a1, mask=a.mask | ~mask).argmin()
    trough_minus  (np.ma.masked_array(a1, mask=a.mask | mask).argmin()
    
    同样,由于蒙版数组具有反转的蒙版,因此使用
    |
    而不是
    &
    来组合蒙版非常重要,这与普通numpy布尔蒙版一样。在这种情况下,不需要调用
    argmax
    argmin
    的nan版本,因为所有nan都已被屏蔽

    鉴于numpy函数中
    axis
    关键字的普遍性,希望从这里可以清楚地概括到多个维度:

    a = np.ma.array(a, mask=np.isnan(a))
    peak_indices = a.argmax(axis=0).reshape(1, *a.shape[1:])
    mask = np.arange(a.shape[0]).reshape(-1, *(1,) * (a.ndim - 1)) >= peak_indices
    
    trough_plus = np.ma.masked_array(a, mask=~mask | a.mask).argmin(axis=0)
    trough_minus = np.ma.masked_array(a, mask=mask | a.mask).argmin(axis=0)
    

    N维掩蔽技术就是从这个目的而来的。

    您可能需要掩蔽数组或np.nanargmax,而不是两者都需要。我会选择后者,因为前者在处理掩蔽的方式上不是很有效。物理学家在某些情况下,我有沿0轴的所有nan值。在没有掩码的情况下,np.nanargmax返回
    ValueError:遇到的所有NaN切片
    @vrlo。你能用-1或什么来代替NAN吗?看起来你的数据都是肯定的…我已经起草了90%的答案,但被卡住了,所以问了另一个问题:好问题。确实给了我一些思考的东西。我看到你找到了我的答案:)我不确定我是否遵循了第6步。紧靠峰值左侧的值可能是下一个全局最大值。给定OP的所有正数据,行最大值将找到该值,而行最小值将立即找到峰值右侧的翻转值。@物理学家记得在步骤4中,我们从每行中减去其最大值,因此,每一行在最大值所在的位置都将有一个零,而在我现在遵循的位置则只有一个非正值。谢谢很酷,谢谢。使用屏蔽阵列还允许我设置一些其他任意约束,我可以屏蔽阵列的其他部分,例如,如果我希望时间序列的峰值和第300天之间的最小值,而不是时间序列的峰值和最后一天之间的最小值