Мой алгоритм случайного воспроизведения падает, когда больше испытаний, чем объектов
Я пытаюсь провести эксперимент, где папка сканируется на наличие изображений. Для каждого испытания показана цель и несколько (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.
Изменить: Добавлена ссылка на вопрос по модулю.