def qualNormGaussian(data, qualitative):
genes, cells = data.shape<EOL>clusters = qualitative.shape[<NUM_LIT:1>]<EOL>output = np.zeros((genes, clusters))<EOL>missing_indices = []<EOL>qual_indices = []<EOL>for i in range(genes):<EOL><INDENT>if qualitative[i,:].max() == -<NUM_LIT:1> and qualitative[i,:].min() == -<NUM_LIT:1>:<EOL><INDENT>missing_indices.append(i)<EOL>continue<EOL><DEDENT>qual_indices.append(i)<EOL>threshold = (qualitative[i,:].max() - qualitative[i,:].min())/<NUM_LIT><EOL>kmeans = KMeans(n_clusters = <NUM_LIT:2>).fit(data[i,:].reshape((<NUM_LIT:1>, cells)))<EOL>assignments = kmeans.labels_<EOL>means = kmeans.cluster_centers_<EOL>high_mean = means.max()<EOL>low_mean = means.min()<EOL>for k in range(clusters):<EOL><INDENT>if qualitative[i,k]>threshold:<EOL><INDENT>output[i,k] = high_mean<EOL><DEDENT>else:<EOL><INDENT>output[i,k] = low_mean<EOL><DEDENT><DEDENT><DEDENT>if missing_indices:<EOL><INDENT>M_init = output[qual_indices, :]<EOL>kmeans = KMeans(n_clusters = <NUM_LIT:2>, init = M_init, max_iter = <NUM_LIT:1>).fit(data[qual_indices, :])<EOL>assignments = kmeans.labels_<EOL>for ind in missing_indices:<EOL><INDENT>for k in range(clusters):<EOL><INDENT>output[ind, k] = np.mean(data[ind, assignments==k])<EOL><DEDENT><DEDENT><DEDENT>return output<EOL>
Generates starting points using binarized data. If qualitative data is missing for a given gene, all of its entries should be -1 in the qualitative matrix.

Args:
    data (array): 2d array of genes x cells
    qualitative (array): 2d array of numerical data - genes x clusters

Returns:
    Array of starting positions for state estimation or
    clustering, with shape genes x clusters