Мой алгоритм случайного воспроизведения падает, когда больше испытаний, чем объектов

Я пытаюсь провести эксперимент, где папка сканируется на наличие изображений. Для каждого испытания показана цель и несколько (7) отвлекающих изображений. После этого в половине испытаний людям показывают целевое изображение, а в другой половине - изображение, которого не было на предыдущем дисплее.

Мой текущий код вроде работает, но только если испытаний меньше, чем объектов:

repeats = 20

# Scan dir for images
jpgs = []

for path, dirs, files in os.walk(directory):
    for f in files:
        if f.endswith('.jpg'):
            jpgs.append(f)

# Shuffle up jpgs
np.random.shuffle(jpgs)

# Create list with target and probe object, Half random, half identical
display = []
question = []
sameobject = []
position = np.repeat([0,1,2,3,4,5,6,7], repeats)
for x in range(1,(repeats*8)+1):
    display.append(jpgs[x])
    if x % 2 == 0:
        question.append(jpgs[-x])
        sameobject.append(0)
    else:
        question.append(jpgs[x])
        sameobject.append(1)

# Concatonate objects together
together = np.c_[display,question,position,sameobject] 
np.random.shuffle(together)

for x in together:
        # Shuffle and set image
        np.random.shuffle(jpgs)
        myList = [i for i in jpgs if i != together[trial,0]]
        myList = [i for i in myList if i != together[trial,1]]

        # Set correct image for target
        myList[int(together[trial,2])] = together[trial,0]

Прежде всего, я знаю, что это ужасный код. Но это делает работу грубо. С 200 JPG и повтор 20, это работает. Если повтор установлен на 30, он падает.

Вот пример с повторением слишком высоко:

  File "H:\Code\Stims\BetaObjectPosition.py", line 214, in <module>
    display.append(jpgs[x])
IndexError: list index out of range

Есть ли способ обновить мой код таким образом, чтобы можно было проводить больше испытаний, пока все объекты используются максимально равномерно (один объект не должен отображаться 3 раза, а другой - 0) в течение всего эксперимента?

Полный воспроизводимый пример

Бонусные баллы, если кто-то может увидеть очевидный способ сбалансировать способ выбора 7 изображений отвлекающих тоже.

Спасибо, что нашли время, чтобы прочитать это. Я надеюсь, что вы можете помочь мне дальше.

1 ответ

Решение, которое меняет ваш код меньше всего должно состоять в том, чтобы изменить каждый вызов jpgs[x] в jpgs[x % len(jpgs)]1 Это должно избавиться от IndexError; он в основном оборачивает индекс списка "по краям", следя за тем, чтобы он никогда не был слишком большим. Хотя я не уверен, как это будет взаимодействовать с jpgs[-x] вызов.

Альтернативой может быть реализация класса, который создает более длинную последовательность объектов из более короткого. Пример:

from random import shuffle


class InfiniteRepeatingSequence(object):
  def __init__(self, source_list):
      self._source = source_list
      self._current = []

  def next(self):
      if len(self._current) == 0:
          # copy the source
          self._current = self._source[:]

          shuffle(self._current)

      # get and remove an item from a list
      return self._current.pop()

Этот класс повторяет список до бесконечности. Он гарантирует использование каждого элемента один раз перед повторным использованием списка. Его легко превратить в итератор (попробуйте изменить next в __next__). Но будьте осторожны, поскольку приведенный выше класс создает бесконечную последовательность элементов.


1 См. " Как работает% в Python?" Для объяснения оператора modulo.

Изменить: Добавлена ​​ссылка на вопрос по модулю.

Другие вопросы по тегам