I am working with 3 pandas dataframes that contain information about differential gene expression for multiple cell groups. It's essentially a multi-dimentional dataframe, where one dataframe (names) is the index of where to look for in the p-value and foldchange dataframes for the corresponding values.
columns = ['g0','g1','g2','g3']
names = pd.DataFrame(data = [
['Fxyd3', 'Apoe', 'Apoe', 'Apoe'],
['Apoe', 'Hspg2', 'Hspg2', 'Ltbp3'],
['Tpm1', 'Ltbp3', 'Ltbp3', 'Hspg2'],
['App', 'Serpinh1', 'Fxyd3', 'Fxyd3'],
['Ltbp3', 'Fxyd3', 'Serpinh1', 'Lgr5'],
['Hspg2', 'Lgr5', 'Lgr5', 'App'],
['Slc6a6', 'App', 'App', 'Serpinh1'],
['Serpinh1', 'Slc6a6', 'Slc6a6', 'Slc6a6'],
['Lgr5', 'Tpm1', 'Tpm1', 'Tpm1'],
['Krt15', 'Krt15', 'Krt15', 'Krt15']],
columns = columns)
np.random.seed(0)
pvalues = pd.DataFrame(data = np.random.rand(10,4)/100, columns = columns)
foldchanges = pd.DataFrame(data =np.random.rand(10,4)*100, columns = columns)
What I would like to do is to find the minimum p-value for each gene and the corresponding foldchange and group name. After hours of trying to wrap my head around this, I came to this solution:
gene_set = ['Hspg2', 'Ltbp3', 'Lgr5', 'Krt15', 'Serpinh1', 'Tpm1', 'App', 'Apoe', 'Slc6a6', 'Fxyd3']
df = pd.DataFrame(index = gene_set, columns = ['pvalues', 'foldchanges', 'group'], data = 0)
for gene in gene_set:
bool_df = names.values == gene
values = pvalues.values[bool_df]
df['pvalues'].loc[gene] = min(values)
df['foldchanges'].loc[gene] = foldchanges.values[bool_df][values==min(values)]
values = pvalues.T.values[bool_df.T] #Fix to get out correct group name
df['group'].loc[gene] = columns[np.where(values==min(values))[0][0]]
Resulting in an output like this:
pvalues foldchanges group
Hspg2 0.004376 21.038256 g2
Ltbp3 0.000202 65.310833 g0
Lgr5 0.004562 97.676109 g0
Krt15 0.006121 28.280696 g0
Serpinh1 0.005218 83.794491 g0
Tpm1 0.000188 73.926358 g2
App 0.001434 82.099323 g2
Apoe 0.004237 66.676672 g0
Slc6a6 0.001183 19.658236 g0
Fxyd3 0.000710 20.887676 g2
Now, my issue is that in the full dataset, I have 20+ groups and around 50,000 genes, which ends up taking about 15-20 minutes to run. And I would like to run this code for multiple datasets. So I was wondering if there maybe is a more elegant and faster way to achieve the same goal?
Edit: Added random seed for reproducibility and added a fix to get out correct group names