Bernoulli trials using a condition in a vectorized operation
To initialize all entries of an array to the same value, np.repeat is probably not the fastest option, and definitely not what most people would expect to find. The more proper way would probably be:

baf = np.full((n.size,), fill_value=np.nan)


And for cases like this it is typically faster to use a boolean mask for indexing, skipping the call to np.where to extract the numerical indices. This should do the same faster:

mask = n &gt;= 30
baf[mask] = np.random.binomial(n[mask], p[mask]).astype(float) / n[mask]