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]
这是一个非常聪明的想法,感谢您提交。