Numpy排序数组的循环错误,但原始工作正常

时间:2018-11-10 22:24:09

标签: python arrays sorting numpy for-loop

在我对此numpy数组进行排序并删除所有重复的(y)值以及重复的(y)值的对应(x)值之后,我使用了for循环在其余坐标处绘制矩形。但是我得到了一个错误:ValueError:太多的值无法解包(预期2),但是它与原始形状相同,只是重复项已被删除。

from graphics import *
import numpy as np

def main():
    win = GraphWin("A Window", 500, 500)

# starting array
startArray = np.array([[2, 1, 2, 3, 4, 7],
              [5, 4, 8, 3, 7, 8]])

# the following reshapes the from all x's in one row and y's in second row
# to x,y rows pairing the x with corresponding y value.
# then it searches for duplicate (y) values and removes both the duplicate (y) and
# its corresponding (x) value by removing the row.
# then the unique [x,y]'s array is reshaped back to a [[x,....],[y,....]] array to be used to draw rectangles.
d = startArray.reshape((-1), order='F')

# reshape to [x,y] matching the proper x&y's together
e = d.reshape((-1, 2), order='C')

# searching for duplicate (y) values and removing that row so the corresponding (x) is removed too.
f = e[np.unique(e[:, 1], return_index=True)[1]]

# converting unique array back to original shape
almostdone = f.reshape((-1), order='C')

# final reshape to return to original starting shape but is only unique values
done = almostdone.reshape((2, -1), order='F')

# print all the shapes and elements
print("this is d reshape of original/start array:", d)
print("this is e reshape of d:\n", e)
print("this is f unique of e:\n", f)
print("this is almost done:\n", almostdone)
print("this is done:\n", done)
print("this is original array:\n",startArray)

# loop to draw a rectangle with each x,y value being pulled from the x and y rows
# says too many values to unpack?
for x,y in np.nditer(done,flags = ['external_loop'], order = 'F'):
    print("this is x,y:", x,y)
    print("this is y:", y)
    rect = Rectangle(Point(x,y),Point(x+4,y+4))
    rect.draw(win)

win.getMouse()
win.close()

main()

这是输出:

line 42, in main
for x,y in np.nditer(done,flags = ['external_loop'], order = 'F'):
ValueError: too many values to unpack (expected 2)
this is d reshape of original/start array: [2 5 1 4 2 8 3 3 4 7 7 8]
this is e reshape of d:
 [[2 5]
 [1 4]
 [2 8]
 [3 3]
 [4 7]
 [7 8]]
this is f unique of e:
 [[3 3]
 [1 4]
 [2 5]
 [4 7]
 [2 8]]
this is almost done:
 [3 3 1 4 2 5 4 7 2 8]
this is done:
 [[3 1 2 4 2]
 [3 4 5 7 8]]
this is original array:
 [[2 1 2 3 4 7]
 [5 4 8 3 7 8]]

为什么for循环适用于原始数组而不适用于这种排序的数组? 还是我可以使用什么循环来仅使用(f),因为它已排序但shape(-1,2)?

我还尝试了一个不同的循环:

for x,y in done[np.nditer(done,flags = ['external_loop'], order = 'F')]:

哪个似乎可以解决太多的值错误,但是我得到了:

IndexError: index 3 is out of bounds for axis 0 with size 2

FutureWarning: Using a non-tuple sequence for multidimensional indexing is 
deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this 
will be interpreted as an array index, `arr[np.array(seq)]`, which will 
result either in an error or a different result.
  for x,y in done[np.nditer(done,flags = ['external_loop'], order = 'F')]:

我已经在stackexchange上进行了修复,但是无论我如何使用语法,都不断收到错误消息。

任何帮助将非常感谢!

1 个答案:

答案 0 :(得分:0)

我没有graphics软件包(可能是Windows专用的东西?),但我确实知道您使此操作变得过于复杂。这是产生相同的done数组的更简单的版本:

from graphics import *
import numpy as np

# starting array
startArray = np.array([[2, 1, 2, 3, 4, 7],
                       [5, 4, 8, 3, 7, 8]])

# searching for duplicate (y) values and removing that row so the corresponding (x) is removed too.
done = startArray.T[np.unique(startArray[1,:], return_index=True)[1]]

for x,y in done:
    print("this is x,y:", x, y)
    print("this is y:", y)
    rect = Rectangle(Point(x,y),Point(x+4,y+4))
    rect.draw(win)

请注意,在以上版本的done.shape==(5, 2)中,而不是(2, 5),但是您可以始终在for循环后使用done = done.T将其改回。

以下是您原始代码的一些注释,供以后参考:

  • order中的reshape标志与您的代码尝试执行的操作完全无关,并且使其变得更加混乱/潜在地增加了错误。没有它,您可以进行所有想要的重塑。

  • nditer的用例是一次迭代一个(或多个)数组的各个元素。通常,它不能用于遍历2D数组的行或列。如果尝试以这种方式使用它,则可能会得到错误的结果,该结果高度依赖于内存中数组的布局(如您所见)。

  • 要迭代2D数组的行或列,只需使用简单的迭代即可。如果仅遍历数组(例如for row in arr:),则会得到每一行,一次一行。如果要使用列,则可以先转置数组(就像我在上面的代码中使用.T所做的那样)。

关于.T

的注释

.T进行数组的转置。例如,如果您以

开头
arr = np.array([[0, 1, 2, 3],
                [4, 5, 6, 7]])

然后转置为:

arr.T==np.array([[0, 4],
                 [1, 5],
                 [2, 6],
                 [3, 7]])