BinkyNichols
BinkyNichols

Reputation: 586

Numpy multidimensional array assigment unknown logic error

I'm confused as to why this bubble sort I'm implementing on a numpy array is setting all items to one of the items (I have no idea which one as array is too big)

the data type is of

...

[[1128 1026 1192 1023]]

[[ 771  195  858  196]]

[[ 953 1799  955 1738]]]

when I have an array of int, this same algorithm sorts it perfectly,

 g = [i for i in range(10)]

for i in range(0,len(g)):
    for j in range(0,len(g)):
        if(g[i]>g[j]):
            cnt = g[i]
            g[i] = g[j]
            g[j] = cnt

I presume my issue is that I do not understand multidimensional numpy array element assigment, please explain why this breaks:

lines = cv2.HoughLinesP(edges, rho, theta, threshold, np.array([]),

                min_line_length, max_line_gap)

sort by an 2nd element of each item

for i in range(0,len(lines)):

    for j in range(0,len(lines)):

        if(lines[i][0][1]<lines[j][0][1]):

            cnt = lines[i][0]

            lines[i][0] = lines[j][0]

            lines[j][0] = cnt[/CODE]

now the array is

[[[ 738 1831  867 1831]]

...

[[ 738 1831  867 1831]]

[[ 738 1831  867 1831]]

[[ 738 1831  867 1831]]]

why? Any help appreciated.

Upvotes: 1

Views: 52

Answers (1)

warped
warped

Reputation: 9491

While you want your code to assign the value of a variable to a new object, your code is interpreted differently:

Quote from the python standard library:

Assignment statements in Python do not copy objects, they create bindings between a target and an object. For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other. This module provides generic shallow and deep copy operations (explained below).

I give an example with lists:

a is initialised as a list with one element that has value 9:

In [1]: a = [9]

Now

In [2]: b = a

while it may look like you just created an object with the same value as a, what this line of code does in actuality, is to create a reference to the same object.

So, assigning a new value to the first element of a will change the underlying object:

In [3]: a[0] = 1

And if the new name you gave this object is called, it will still reference to that object:

In [4]: b
Out[4]: [1]

To avoid unwanted behaviour, you should use copy:

In [1]: import copy

In [2]: a = [9]

In [3]: b = copy.copy(a)

In [4]: a[0] = 1

In [5]: b
Out[5]: [9]

np.arrays have a .copy() method, that you can call like so, without importing copy:

a = np.array([1,2,3])
b = a.copy()

Upvotes: 1

Related Questions