Procedural generation of a general matrix representing a tile map
You don't need to create a second m x n matrix to track where you've set. Since you're only interested in the index of the last one placed in each column you can use an one dimensional n-length array to track the row of the last one added and then use that directly when indexing the matrix.
Similarly, it also lets you randomly choose columns that still have space to add ones directly (that is, the nber of ones added is less than the length of the column) using np.less, np.where, and np.random.choice instead of picking a column, checking if it contains all ones, and resampling if it does. That's almost always a bad approach, especially when you start to have more columns full than not. If there are 5 full columns and 1 non-full one you have to keep sampling until you randomly select the one non-full column with only 1/6th odds which is going to be slow.
Combining all that you can write everything you need in about 8 lines with a 6-7x speed up
def matrix_generator(m, n): 
    matrix = np.zeros((m,n), dtype=&quot;int&quot;)
    ones = np.zeros(n, dtype=&quot;int&quot;)

    while np.any(np.less(ones, m)):
        i = np.random.choice(np.where(np.less(ones, m))[0])

        matrix[ones[i],i] = 1
        ones[i] += 1

        yield matrix