对象列表:如何从特定区域或切片中提取属性?

时间:2015-10-03 08:26:22

标签: python numpy multidimensional-array slice

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

enter image description here

我已经阅读了有关如何从整个列表中提取属性的其他问题,并且使用列表推导可以轻松地从行和列中提取,但是我无法理解如何执行此操作,例如,对于第2个和第四个切片显示在图像中,尤其是第四个切片。

这对我正在制作的棋盘游戏很有用,我可以切割棋盘并检查,例如,一组磁贴是否具有特定值或者它们是否共享特定属性。

1 个答案:

答案 0 :(得分:1)

您只想检查它们是否具有共同属性,而不是通过调整索引结果将其减少为1D-Case。

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])

因为看起来1D案例可以为你解决(使用列表推导),这可能只是诀窍。但是对于列表推导,你必须要知道,如果你不想要一个axis的数组作为结果,那么多维数组应该是ravelled或flattened(参见numpy文档)。

对于简单的情况,您可能只想在没有np.allflatten的情况下使用ravel函数:

#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)