我正在尝试做一个实验,扫描文件夹中的图像。对于每个试验,都会显示一个目标和一些(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个重复,它就可以工作了。如果repeat设置为30,它将崩溃。
下面是一个重复次数过高的例子:
File "H:CodeStimsBetaObjectPosition.py", line 214, in <module>
display.append(jpgs[x])
IndexError: list index out of range
有没有一种方法可以更新我的代码,允许在整个实验中尽可能均匀地使用所有对象(一个对象不应显示3次,而另一个对象显示0次(的同时进行更多的试验?
完整、可复制的示例
如果有人能看到一种明显的方法来平衡7张干扰图像的选择方式,则可以获得加分。
感谢您花时间阅读本文。我希望你能继续帮助我。
更改代码最少的解决方案应该是将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中如何工作?"。
编辑:添加模块问题链接。