PsychoPy Builderで複数の刺激をランダムに呈示する(その2)

      PsychoPy Builderで複数の刺激をランダムに呈示する(その2) はコメントを受け付けていません

前回の記事で,画面に2つの画像刺激を呈示するような実験において,それぞれの刺激の呈示順序をランダムに設定する方法について解説しました。今回は,刺激の呈示順序はランダムにしたい,けど特定の刺激ペアが呈示されるのは避けたい (今回の実験では1L.pngと1R.png, 4L.pngと4R.png など,数字が同じペア),というニッチな需要に対処します。なお,結構な力技ですので,他にもっと良い解がある可能性もあることをお断りしておきます。

前回のコードだと,作成される条件ファイルは毎回ランダムなので,上記のような避けたい刺激ペアも生じる可能性があります。それらの組み合わせを避けて並べ替え(抽出)を行うような関数があればよいのですが,探した限りでは見つかりませんでした。そこで,力技に出ることにします。以下のコードをcodeコンポーネントの”Begin Experiment”に貼り付けます。

import pandas as pd
import numpy as np

df_L=pd.Series(["1L.png","2L.png","3L.png","4L.png","5L.png","6L.png","7L.png","8L.png","9L.png","10L.png","11L.png","12L.png"])
df_R=pd.Series(["1R.png","2R.png","3R.png","4R.png","5R.png","6R.png","7R.png","8R.png","9R.png","10R.png","11R.png","12R.png"])

LRdif=[0]
while 0 in LRdif:
     df_Lr=df_L.sample(frac=1)
     df_Rr=df_R.sample(frac=1)
     df_Lr=df_Lr.reset_index()
     df_Rr=df_Rr.reset_index()
     df_LR=pd.merge(df_Lr,df_Rr,left_index=True,right_index=True)
     df_LR['dif']=df_LR.index_x - df_LR.index_y
     LRdif=df_LR['dif'].values.tolist()
else:df_cond=pd.DataFrame({'image1':df_LR['0_x'],'image2':df_LR['0_y']})

df_cond.to_csv('conditionfile.csv', index=False)

pandasに加えて,行列演算を行うためのライブラリであるnumpyをインポートしています。画像刺激のセットを作る部分(4, 5行目)までは前回と同様です。7行目では,”LRdif”という変数に0を代入しています。8行目以降のwhile文ですが,内部で行っていることは,前回のコードと同様に,2つの刺激セットをランダムに並べ替えて結合しています。

前回のコードと異なる点として,14行目では,2つの刺激セットの元々のインデックスの引き算を行っています。こうすることで,数値が同じ画像刺激がペアになった場合,引き算の結果は”0”になります。15行目では引き算の結果を”LRdif”に渡しています。すなわち,このwhile文は,数値が同じ画像刺激のペアが含まれなくなるまで (”LRdif”に”0”が含まれなくなるまで) データフレームを作り直す,という処理を行っています。while文が解決されたら (数値が同じ刺激ペアを含まないデータフレームが作成されたら) ,18行目でcsvファイルとして保存します。

今回の実験では,刺激は左右合計で24項目だけなので,比較的スムーズに処理が終わりますが,刺激数がもっと増えたときにどのような挙動になるかは分かりません。もっと良い解をご存知の方は教えていただけると嬉しいです。