Numpy отсортированный массив для ошибки цикла, но оригинальный работает нормально - PullRequest
0 голосов
/ 11 ноября 2018

После того, как я отсортирую этот массив и удаляю все повторяющиеся значения (y) и соответствующее значение (x) для значения duplicate (y), я использую цикл 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), поскольку он отсортирован, но форма (-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 голосов
/ 11 ноября 2018

У меня нет пакета 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 - перебирать отдельные элементы одного (или более) массива по одному за раз. Обычно его нельзя использовать для перебора строк или столбцов двумерного массива. Если вы попытаетесь использовать его таким образом, вы, вероятно, получите ошибочные результаты, которые сильно зависят от расположения массива в памяти (как вы видели).

  • Чтобы перебрать строки или столбцы двумерного массива, просто используйте простую итерацию. Если вы просто перебираете массив (например, 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]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...