Randomly shuffle two sets of columns while preserving intra-group order

OS (e.g. Win10): Win 10
PsychoPy version (e.g. 1.84.x): 3.0.5
**Standard Standalone? **: y
What are you trying to achieve?:
In my task, participants must rate images and odors on a number of dimensions. I have everything set up, but a last minute change has left me puzzled.
Initially, participants would rate all images, and then all odors. I had two routines, each drawing from the same .csv file:


However, now ratings must alternate between images and odors so that a participant sees an image, then smells an odor, sees an image, etc.
I would still like to use two routines, one routine for images and one for odors. I also want to have one loop around both routines. So it would go Image routine x1, odor routine x 1, and then loop and start over. It would repeat this procedure 8 times:


I think the easiest way to do this would be to have one .csv file with images in one column, and odors in another column. Then, at the start of the experiment the .csv file would have each column shuffled separately. I have found some resources for a variety of ways to do this, but I have one difference the previous examples did not have: there are more than just these two columns tied to each routine. Therefore, I need a way to shuffle two groups of columns independently, while still preserving the order within the two groups.
For example, My .csv file has 8 columns, and 4 rows. Columns 1:4 are for image ratings, and Columns 5:8 are for odor ratings. I want to shuffle Columns 1:4 independently from Columns 5:8 without changing the within image order (Columns 1:4) or within odor order (Columns 5:8). That way, the image rating routine would draw random rows from Columns 1:4, and the olfactory rating routine would draw from Columns 5:8. But, these groups of columns would be reordered for each participant while preserving the order within each group of columns.
Any help would be greatly appreciated.

Thank you,

A couple of caveats:

  • This is very much a hack
  • It involves setting everything up in the Builder and then making some simple changes in the Coder

This is the flow:

  • You have two separate input files associated with the loops trials1 and trials2
    • For both loops, loopType is random, and Is trials is unchecked
  • The outer loop trials simply has as many nReps as there are trials in the inner loops, and Is trials is checked

The basic idea is this:

  • The TrialHandler definitions for trials1 and trials2 are made before entering the trials loop (see attached Coder version)
    • In the Coder, you need to cut and paste the corresponding sections (see attachment)
  • You break out of the inner loops after each routine
    • In the Coder, you need to add break statements at the end of the inner trial routines
    • This appears to work because the TrialHandler uses masked arrays to keep track of what has already been presented (is this correct, @dvbridges?)

Please find a simple working (I think so at least) example attached.

Hope this helps.


separate_randomisations_initial.psyexp (8.3 KB)
input1.xlsx (8.5 KB)
input2.xlsx (8.5 KB)
separate_randomisations_and_break_Coder.py (13.1 KB)

1 Like

Hello @jderrfuss

Your explanation has been very useful. I had exactly the same situation (posted here https://bit.ly/2Pc1ZEX) and did not have any idea about how to solve it.

I have applied the changes you say to my code and everything seems to work except that the trial data is not saved. I think it has to do with this_

As far as I know, when I uncheck the “trials” box in my inner loops, the program does not save any information at that level (where I actually have the important information)

I would appreciate any idea!



I’d recommend preloading the items into lists using my interleaved lists method.

1 Like


I am thinking about how to apply the interleaved lists method to my experiment.
As I understand, the guidelines you provide here are thought to be used with 2 different routines (one for fillers and one for targets, in my case… one for CAT trials and one for SEL trials) but a single spreadsheet containing both types of trials. Am I right?

If you load them from one spreadsheet then you could do it in a single loop. However, you’d then need to shuffle one of the lists to make sure they are independent. You could use two loops and use one or two spreadsheets.