有效检查数组是否有锯齿

Dil*_*rix 5 python arrays numpy

我正在寻找一种有效的方法来检查数组是否是锯齿状的,其中“锯齿状”意味着数组中的一个元素与它在同一维度上的相邻元素具有不同的形状。

例如[[1, 2], [3, 4, 5]][[1, 2], [3, 4], [5, 6], [[7], [8]]]

为方便起见,我使用列表语法,但参数可能是嵌套列表或嵌套的 numpy 数组。为了方便起见,我还显示了整数,最低级别的组件可以是任何东西(例如通用对象)。假设最低级别的对象本身不可迭代(例如strdict,但对于可以处理这些问题的解决方案来说绝对是加分项!)。

尝试:

递归地平坦化的阵列是相当容易的,虽然我猜相当高效,然后将扁平阵列的长度可以相对于numpy.size输入数组的。如果它们匹配,则它不是锯齿状的。

def really1d(arr):
    # Returns false if the given array is not 1D or is a jagged 1D array.
    if np.ndim(arr) != 1:
        return False
    if len(arr) == 0:
        return True
    if np.any(np.vectorize(np.ndim)(arr)):
        return False
    return True


def flatten(arr):
    # Convert the given array to 1D (even if jagged)
    if (not np.iterable(arr)) or really1d(arr):
        return arr
    return np.concatenate([flatten(aa) for aa in arr])


def isjagged(arr):
    if (np.size(arr) == len(flatten(arr))):
        return False
    return True
Run Code Online (Sandbox Code Playgroud)

我很确定串联会复制所有数据,这完全是浪费。也许有一种itertoolsnumpy.flatiter方法可以实现相同的目标?最终,扁平数组用于查找其长度。

Anw*_*vic -2

有一种超级简单的方法可以在一行中完成......只需一行。它并不完美,但非常简单。

您可以使用np.array. 如果嵌套列表的所有元素都具有相同的形状,则生成的数组的维度将多于一维。但如果只有一个元素具有不同数量的元素,则返回的数组将是一维的。

请参阅此示例以获取更多理解:

>>> import numpy as np
>>> lst = [[1, 2], [3, 4, 5]]
>>> arr = np.array(lst)
>> arr.shape
(2,)
>>> arr.dtype
object

>>> lst = [[0, 1, 2], [3, 4, 5]]
>>> arr = np.array(lst)
>>> arr.shape
(2, 3)
>>> arr.dtype
int64
Run Code Online (Sandbox Code Playgroud)

因此,您的函数将只用一行编写,如下所示:

def isjagged(lst):
    return len(np.array(lst).shape) == 1
Run Code Online (Sandbox Code Playgroud)

注意:当然这仅适用于嵌套列表

编辑

正如 @Ch3steR 所说,该解决方案适用于简单的嵌套列表,但不适用于像这样的有点复杂的嵌套列表:[[1, 2], [3, 4], [5, 6], [[7], [8]]]

所以,我认为这可能是一个更好的解决方案:

def isjagged(lst):
    return np.array(lst).dtype == 'object'
Run Code Online (Sandbox Code Playgroud)