【问题标题】:List of objects: how to extract attributes from a particular region or slice?对象列表:如何从特定区域或切片中提取属性?
【发布时间】:2015-12-31 10:45:39
【问题描述】:

这张来自 numpy 文档的图片让我感到疑惑。如果它是一个包含具有共同属性的对象的多维列表(或ndarray),如何从特定部分中提取它?

我已经阅读了有关如何从整个列表中提取属性以及使用列表推导从行和列中提取属性的其他问题,但我无法理解如何做到这一点,例如,对于第二个和图像中显示的第 4 个切片,尤其是第 4 个切片。

这对于我正在制作的棋盘游戏很有用,例如,我可以切开棋盘并检查一组图块是否具有特定值或它们是否具有特定属性。

【问题讨论】:

    标签: python numpy multidimensional-array slice


    【解决方案1】:

    您只想检查它们是否具有共同的属性,而不是通过分解索引结果将其简化为一维案例。

    array = np.arange(25).reshape(5,5)
    array[2::2,2::2] # Gives you: array([[12, 14], [22, 24]])
    array[2::2,2::2].ravel() #Gives you: array([12, 14, 22, 24])
    

    因为看起来一维案例是可以解决的(使用列表推导),这可能只是诀窍。但是对于列表推导,您必须注意,如果您不想要 axis 的数组作为结果,则应该将多维数组解散或展平(参见 numpy 文档)。

    对于简单的情况,您可能只想使用np.all 函数而不使用flattenravel

    #Just check if they are all multiplicatives of 2
    np.all((array[2::2,2::2] % 2) == 0) # Gives you True
    #Just check if they are all multiplicatives of 3
    np.all((array[2::2,2::2] % 3) == 0) # Gives you False
    

    但还有另一种方式:numpy 提供了一个 np.nditer 迭代器 (http://docs.scipy.org/doc/numpy/reference/arrays.nditer.html),你可以用它来做一些漂亮的事情。就像一个非常简单的例子:

    #Supposing you check for an attribute
    def check_for_property(array, property_name, property_state):
       #property_name: str (The name of the property you want to check(
       #property_state: anything (Check if the property_name property of all elements matches this one)
       #The returns act as a shortcut so that the for loop is stopped after the first mismatch.
       #It only returns True if the complete for loop was passed.
       for i in np.nditer(array):
           if hasattr(i, property_name):
              if getattr(i, property_name) != property_state:
                  return False #Property has not the same value assigned
           else:
              return False # If this element hasn't got this property return False
       return True #All elements have the property and all are equal 'property_state'
    

    如果您希望它很小(并且您的检查相对容易),那么带有 np.allnp.nditer 的列表理解可能如下所示:

    np.all(np.array([i.property for i in np.nditer(array[2::2,2::2])]) == property_state)
    

    【讨论】:

    • 非常翔实和详细的答案!尽管我使用的是flatten(),但我在发布我的问题后不久就采用了同样的方法。我可以切换到ravel(),因为我不需要数组的副本。而且我认为列表推导或生成器表达式足以进行快速检查,但了解如何在循环中使用 nditer 非常棒。此外,您的第一行 (np.arange(50).reshape(5,5)) 在我的末尾抛出了 ValueError。非常感谢!
    • @absay 只要你不改变数据ravel 更好,但flatten 提供相同的功能。很抱歉第一行,这是我这边的 C&P 错误,我会更改它。
    猜你喜欢
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-13
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多