Issue
I want to create python array that have the numbers one to 42 in the first column and the numbers 1 and 3 in the second column, but with special conditions. I want that there are pairs of 1,3 and 3,1.
I actually got code that works, but it's pretty slow. Maybe anyone of you have a faster solution.
import numpy as np
import random
trials=np.linspace(1,42,42)
vec1=np.ones(21)
vec2=vec1+2
trial_types=np.concatenate((vec1,vec2))
isok=0
numb_run=1
while isok == 0:
random.shuffle(trial_types)
break_con = 0
i=1
while i <= len(trial_types):
if trial_types[i] == trial_types[i - 1]:
break_con = 1
if break_con == 1:
break
i +=2
numb_run+=1
if break_con == 0:
isok=1
print(trial_types)
print(numb_run)
I shuffle and compare an equal entry with an unequal and look if they are the same. If this on time happens i shuffles again. But it takes sometime until with this randomize it happens that the column I am trying to create looks like this:
[3. 1. 3. 1. 3. 1. 1. 3. 1. 3. 3. 1. 1. 3. 1. 3. 3. 1. 3. 1. 3. 1. 1. 3.
3. 1. 1. 3. 3. 1. 1. 3. 3. 1. 3. 1. 3. 1. 3. 1. 3. 1.]
711799
And as you can see it takes 700K shuffles to get there. Do you have any ideas how i can make it faster ? I also tried with some kind of np.tile([1,3]) and np.tile([3,1]) but unfortunately 42/4 is not a equal number.
Cheers
Solution
use numpy
import numpy as np
pairs = np.array([[3,1], [1,3]])
pairs[np.random.randint(2,size=21)].flatten()
array([3, 1, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 1, 1, 3, 1, 3,
3, 1, 3, 1, 1, 3, 3, 1, 3, 1, 1, 3, 3, 1, 1, 3, 1, 3, 1, 3])
Each time you run you will get different results but still pairs of (3,1) and (1, 3)
Instead of shuffling the whole array of 42 values, shuffle just one pair ie 3,1 or 1,3 and the append that. until you get 42. Below code describes one way
np.r_[*[np.random.choice([1,3],2,replace = False) for i in range(21)]]
array([3, 1, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 1, 1, 3, 3, 1, 3, 1,
1, 3, 3, 1, 1, 3, 1, 3, 1, 3, 1, 3, 3, 1, 3, 1, 1, 3, 1, 3])
Answered By - Onyambu
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.