Home > front end >  NumPy: How to check if a tuple is in a 1D numpy array
NumPy: How to check if a tuple is in a 1D numpy array

Time:10-24

I'm having some trouble trying to check if a python tuple is in a one dimensional numpy array. I'm working on a loop that will record all the colors present in an image and store them into an array. It worked well using normal lists, but the image is very large and I think NumPy Arrays will speed up the loop as it took several minutes to complete the loop.

Here's what the code looks like:

from PIL import Image
import numpy as np

img = Image.open("bg.jpg").convert("RGB")
pixels = img.load()

colors = np.array([])

for h in range(img.size[1]):
    for w in range(img.size[0]):
        if pixels[w,h] not in colors:
            colors = np.append(colors, pixels[w,h])
        else:
            continue

When I run this, I get the following error:

DeprecationWarning: elementwise comparison failed; this will raise an error in the future.
  if pixels[w,h] in colors:

Thanks in advance, and if you know a faster way to do this please let me know.

CodePudding user response:

I'm not sure what you need exactly. But i hope the next piece of code will help you.

import numpy as np

image = np.arange(75).reshape(5, 5, 3) % 8

# Get the set of unique pixles
pixel_list = image.reshape(-1, 3)
unique_pixels = np.unique(pixel_list, axis = 0)

# Test whether a pixel is in the list of pixels:
i = 0
pixel_in_list = (unique_pixels[i] == pixel_list).all(1).any(0)
# all(1) - all the dimensions (rgb) of the pixels need to match
# any(0) - test if any of the pixels match

# Test whether any of the pixels in the set is in the list of pixels:
compare_all = unique_pixels.reshape(-1, 1, 3) == pixel_list.reshape(1, -1, 3)
pixels_in_list = compare_all.all(2).any()
# all(2) - all the dimensions (rgb) of the pixels need to match
# any()  - test if any of the pixelsin the set matches any of the pixels in the list

CodePudding user response:

How to check if a tuple is in a 1D numpy array:

>>> colors = [(1,2,3),(4,5,6)]
>>> for x in colors:
    print(x)
    if isinstance(x, tuple):
        print("is tuple")

        
(1, 2, 3)
is tuple
(4, 5, 6)
is tuple

But you should use a list instead of numpy array. The error is clear, the feature is deprecated. This is an answer to the question asked in the title.

CodePudding user response:

I found a faster way to make my loop run faster without NumPy and that is by using sets, which is way faster than using lists or NumPy. This is what the code looks like now:

from PIL import Image

img = Image.open("bg.jpg").convert("RGB")
pixels = img.load()

colors = set({})

for h in range(img.size[1]):
    for w in range(img.size[0]):
        if pixels[w,h] in colors:
            continue
        else:
            colors.add(pixels[w,h])

This solves my initial problem of the lists being too slow to loop through, and it goes around the second problem of NumPy unable to compare the tuples. Thanks for all the replies, have a good day.

  • Related