Почему этот код выдает «TypeError: не может распаковать не повторяемый объект int» после того, как он какое-то время работал? - PullRequest
0 голосов
/ 31 октября 2019

Вот отображаемый сегмент заголовка информационного кадра, с которым я работаю.

Это в блокноте Jupyter!

Я пытаюсь заполнитьпустой столбец (полный np.nan) baseData с именем «Средний цвет». Каждый элемент этого столбца представляет средний цвет изображения, загруженного из соответствующего «значка URL».

Вот мой код :

def compute_average_image_color(img):
    width, height = img.size
    r_total = 0
    g_total = 0
    b_total = 0
    count = 0
    for x in range(0, width):
        for y in range(0, height):
            r, g, b = img.getpixel((x,y))
            r_total += r
            g_total += g
            b_total += b
            count += 1
    return (r_total/count, g_total/count, b_total/count)

def get_average_color(URL):
    if URL != np.nan:
        urllib.request.urlretrieve(URL, "local.jpg")
        with Image.open("local.jpg") as img:
            img = img.resize((50,50)) #To make this run MUCH faster.
            return compute_average_image_color(img)

baseData["Average Colour"] = baseData["Icon URL"].apply(lambda x: get_average_color(x))

compute_average_image_color ():не мое, и я знаю, что это работает. Насколько я могу судить, get_average_color () работает как задумано. Этот код выполняется за 37 итераций до сбоя с помощью:

TypeError                                 Traceback (most recent call last)
<ipython-input-51-1675bd6f49ad> in <module>
     41             return compute_average_image_color(img)
     42 
---> 43 baseData["Average Colour"] = baseData["Icon URL"].apply(lambda x: get_average_color(x))
     44 
     45 

~\Anaconda3\lib\site-packages\pandas\core\series.py in apply(self, func, convert_dtype, args, **kwds)
   3589             else:
   3590                 values = self.astype(object).values
-> 3591                 mapped = lib.map_infer(values, f, convert=convert_dtype)
   3592 
   3593         if len(mapped) and isinstance(mapped[0], Series):

pandas/_libs/lib.pyx in pandas._libs.lib.map_infer()

<ipython-input-51-1675bd6f49ad> in <lambda>(x)
     41             return compute_average_image_color(img)
     42 
---> 43 baseData["Average Colour"] = baseData["Icon URL"].apply(lambda x: get_average_color(x))
     44 
     45 

<ipython-input-51-1675bd6f49ad> in get_average_color(URL)
     39         with Image.open("local.jpg") as img:
     40             img = img.resize((50,50)) #To make this run MUCH faster.
---> 41             return compute_average_image_color(img)
     42 
     43 baseData["Average Colour"] = baseData["Icon URL"].apply(lambda x: get_average_color(x))

<ipython-input-51-1675bd6f49ad> in compute_average_image_color(img)
     27     for x in range(0, width):
     28         for y in range(0, height):
---> 29             r, g, b = img.getpixel((x,y))
     30             r_total += r
     31             g_total += g

TypeError: cannot unpack non-iterable int object

Я просмотрел свою электронную таблицу, и нет ничего особенного в индексе 37 или в тех, что вокруг него (35-39), поэтому яне уверен, почему это происходит только после 37 прогонов. Указанный индекс имеет значок URL "https://is1 -ssl.mzstatic.com / image / thumb / Purple4 / v4 / e6 / 88/05 / e688059e-2809-4f8f-9f78-cb7ceb7b461b / source / 512x512bb. jpg", который, кажется, не является чем-то особенным.

Кроме того, этот лист имеет длину 17000 индексов, и Jupyter Notebook, кажется, работает только со скоростью 1 секунда. Это просто Jupyter искусственно медленный? Я очень на это надеюсь, так как это означает, что я могу запустить его намного быстрее за .py .

1 Ответ

0 голосов
/ 31 октября 2019

Есть вероятность, что URL может быть invalid. Если URL-адрес недействителен, результирующее изображение будет 2 dimensions из PIL. Поэтому, чтобы быть на более безопасной стороне, преобразуйте изображение в массив numpy и используйте векторизованный подход, как показано ниже, который намного быстрее, чем для циклов.

import numpy as np 
def compute_average_image_color(img):
    img = np.array(img)
    try:
        r_mean = img[:,:,0].mean()
        g_mean = img[:,:,1].mean()
        b_mean = img[:,:,2].mean()
        return (r_mean,g_mean,b_mean)
    except:
        mean = img.mean()
        return (mean,mean,mean)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...