Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.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 在三维阵列中沿轴查找最长的连续零_Python_Arrays_Numpy - Fatal编程技术网

Python 在三维阵列中沿轴查找最长的连续零

Python 在三维阵列中沿轴查找最长的连续零,python,arrays,numpy,Python,Arrays,Numpy,如何在三维阵列中沿特定轴找到最长的连续零 import numpy as np a = np.random.randint(2, size=(10, 10, 10)) 我想沿着axis=0找到0的最长序列,这样我就得到了一个10x10数组 在一个维度中,它与: import numpy as np a = np.random.randint(2, size=100) condition = (a==0) L = np.diff(np.where(np.concatenate(([co

如何在三维阵列中沿特定轴找到最长的连续零

import numpy as np 

a = np.random.randint(2, size=(10, 10, 10))

我想沿着
axis=0
找到
0
的最长序列,这样我就得到了一个
10x10
数组

在一个维度中,它与:

import numpy as np 
a = np.random.randint(2, size=100)

condition = (a==0)
L = np.diff(np.where(np.concatenate(([condition[0]],
                                     condition[:-1] != condition[1:],
                                     [True])))[0])[::2]
print(np.max(L))

您可以使用
np.cumsum()。
其思想是,当你有连续的零时,总和中的值保持不变。因此,最后您需要找到这个数组中最常见的值,因为它的计数正好是最长的零序列(+1)的长度

不幸的是,
bincount
仅适用于1D数组,因此对于多维情况,我切换到
scipy.stats.mode
,它只返回模态(最常见)值及其计数

# 1D, stats.mode 
c2 = mode(b)
# ModeResult(mode=array([4]), count=array([5]))
res = c2[1] - 1

# 3D, stas.mode
from scipy.stats import mode
axis = 0
a = np.random.randint(2, size=(10, 10, 10))
res = mode(np.cumsum(a, axis=axis), axis=axis)[1] - 1
# Note the resulting shape is (1, 10, 10) 
# You might want to use np.squeeze() / np.max() 
# to get rid of the dimension with size 1
# res = res.max(axis=axis)
编辑 正如@clearseplex指出的,我没有想到数组以0开头的情况

a = np.array([0, 0, 0, 1, 1, 0, 1, 0, 0, 1])

b = np.cumsum(a)
# array([0, 0, 0, 1, 2, 2, 3, 3, 3, 4])
#        ^  ^  ^
有3个零,但是如果我减去一个,我会得到错误的结果。因此,正确的解决方案是仅当最常见的值不是
0
时才进行减法。 因此,正确的方法是:

m, res = mode(np.cumsum(a, axis=axis), axis=axis)
res[m != 0] -= 1
# res = res.argmax(axis)

您可以使用
np.cumsum()。
其思想是,当你有连续的零时,总和中的值保持不变。因此,最后您需要找到这个数组中最常见的值,因为它的计数正好是最长的零序列(+1)的长度

不幸的是,
bincount
仅适用于1D数组,因此对于多维情况,我切换到
scipy.stats.mode
,它只返回模态(最常见)值及其计数

# 1D, stats.mode 
c2 = mode(b)
# ModeResult(mode=array([4]), count=array([5]))
res = c2[1] - 1

# 3D, stas.mode
from scipy.stats import mode
axis = 0
a = np.random.randint(2, size=(10, 10, 10))
res = mode(np.cumsum(a, axis=axis), axis=axis)[1] - 1
# Note the resulting shape is (1, 10, 10) 
# You might want to use np.squeeze() / np.max() 
# to get rid of the dimension with size 1
# res = res.max(axis=axis)
编辑 正如@clearseplex指出的,我没有想到数组以0开头的情况

a = np.array([0, 0, 0, 1, 1, 0, 1, 0, 0, 1])

b = np.cumsum(a)
# array([0, 0, 0, 1, 2, 2, 3, 3, 3, 4])
#        ^  ^  ^
有3个零,但是如果我减去一个,我会得到错误的结果。因此,正确的解决方案是仅当最常见的值不是
0
时才进行减法。 因此,正确的方法是:

m, res = mode(np.cumsum(a, axis=axis), axis=axis)
res[m != 0] -= 1
# res = res.argmax(axis)

要执行任务,请定义以下功能:

def longestZeroSeqLength(a):
    # Changes in "isZero" for consecutive elements
    chg = np.abs(np.diff(np.equal(a, 0).view(np.int8), prepend=[0], append=[0]))
    # Ranges of "isZero" elements
    rng = np.where(chg == 1)[0]
    if rng.size == 0: return 0    # All non-zero elements
    rng = rng.reshape(-1, 2)
    # Compute length of each range and return the biggest
    return np.subtract(rng[:,1], rng[:,0]).max()
然后将其应用于阵列:

result = np.apply_along_axis(longestZeroSeqLength, 0, a)
为了测试它,我创建了以下(较小的)阵列:

运行代码后,我得到:

array([[1, 0, 2, 2, 0],
       [1, 2, 1, 0, 3],
       [3, 1, 1, 1, 0],
       [1, 1, 2, 2, 3]], dtype=int64)
更容易评估每个切片包含的内容以及每个部分是什么 结果,您可以运行:

for j in range(a.shape[1]):
    for k in range(a.shape[2]):
        b = a[:, j, k]
        res = longestZeroSeqLength(b)
        print(f'{j}, {k}: {b}, {res}')

要执行任务,请定义以下功能:

def longestZeroSeqLength(a):
    # Changes in "isZero" for consecutive elements
    chg = np.abs(np.diff(np.equal(a, 0).view(np.int8), prepend=[0], append=[0]))
    # Ranges of "isZero" elements
    rng = np.where(chg == 1)[0]
    if rng.size == 0: return 0    # All non-zero elements
    rng = rng.reshape(-1, 2)
    # Compute length of each range and return the biggest
    return np.subtract(rng[:,1], rng[:,0]).max()
然后将其应用于阵列:

result = np.apply_along_axis(longestZeroSeqLength, 0, a)
为了测试它,我创建了以下(较小的)阵列:

运行代码后,我得到:

array([[1, 0, 2, 2, 0],
       [1, 2, 1, 0, 3],
       [3, 1, 1, 1, 0],
       [1, 1, 2, 2, 3]], dtype=int64)
更容易评估每个切片包含的内容以及每个部分是什么 结果,您可以运行:

for j in range(a.shape[1]):
    for k in range(a.shape[2]):
        b = a[:, j, k]
        res = longestZeroSeqLength(b)
        print(f'{j}, {k}: {b}, {res}')

您想要的
10x10
数组的内容是什么?沿该轴最长连续零的零计数?@HansHirse是沿第零轴最长连续零序列的长度。所需
10 x 10
数组的内容是什么?沿该轴最长连续零的零计数?@HansHirse是沿第零轴最长连续零序列的长度。我认为您的代码没有考虑边缘上的零。
siz=(10,10)np.random.seed(1)a=np.random.randint(2,size=siz)
给出了
[3 2 3 1 2 2 7]
但是应该是
[3 3 3 1 3 2 2 8]
这是一个非常聪明的主意,谢谢你提交。我认为你的代码没有考虑到边缘的零。
siz=(10,10)np.random.seed(1)a=np.random.randint(2,size=siz)
给出了
[3 2 3 1 2 7]
但应该是
[3 3 3 3 1 2 2 2 8]
这是一个非常聪明的想法,感谢您提交。