如何解决根据另一个数据集中的元素位置过滤熊猫数据帧的快速方法
我正在处理3个熊猫数据框,其中包含有关多个细胞组差异基因表达的信息。它本质上是一个多维数据框,其中一个数据框(名称)是在p值中查找位置的索引,而对应值的foldchange数据框则是索引。
columns = ['g0','g1','g2','g3']
names = pd.DataFrame(data = [
['Fxyd3','Apoe','Apoe'],['Apoe','Hspg2','Ltbp3'],['Tpm1','Ltbp3','Hspg2'],['App','Serpinh1','Fxyd3','Fxyd3'],['Ltbp3','Lgr5'],['Hspg2','Lgr5','App'],['Slc6a6','App','Serpinh1'],['Serpinh1','Slc6a6','Slc6a6'],['Lgr5','Tpm1','Tpm1'],['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)
我想做的是找到每个基因的最小p值以及相应的倍数变化和组名。经过数小时的尝试,我终于找到了这个解决方案:
gene_set = ['Hspg2','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]]
产生这样的输出:
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
现在,我的问题是,在整个数据集中,我有20多个组和大约50,000个基因,运行大约需要15-20分钟。我想针对多个数据集运行此代码。所以我想知道是否可能有一种更优雅,更快捷的方法来实现相同的目标?
编辑::添加了可重复性的随机种子,并添加了修复程序以获取正确的组名
解决方法
将所有相关数据包含在数据框的主体中至关重要,从这个意义上讲,melt()
函数是组织数据的重要盟友。
df_melted = pd.melt(pvalues,var_name="group",value_name="pvalues")
df_melted['foldchanges'] = pd.melt(foldchanges,value_name="foldchanges")['foldchanges']
df_melted['gene'] = pd.melt(names,value_name="gene")['gene']
现在,您可以简单地进行一些基本分组以获取具有最小pvalues
的索引
min_idx = df_melted.groupby(by=["gene"])["pvalues"].idxmin()
out_df = df_melted.iloc[min_idx]
某些格式可获取所需格式的输出
out_df = out_df.set_index('gene').rename_axis(None)[['pvalues','foldchanges','group']]
你很好走
pvalues foldchanges group
Apoe 0.004237 66.676672 g0
App 0.001434 82.099323 g2
Fxyd3 0.000710 20.887676 g2
Hspg2 0.004376 21.038256 g2
Krt15 0.006121 28.280696 g0
Lgr5 0.004562 97.676109 g0
Ltbp3 0.000202 65.310833 g0
Serpinh1 0.005218 83.794491 g0
Slc6a6 0.001183 19.658236 g0
Tpm1 0.000188 73.926358 g2
,
我想避免循环以加快处理过程。因此,我们将三个数据帧重组为一个长格式。将它们分组到一个新的数据框中,并汇总最小p值。使用获得的基因名称和P值提取一个新的数据框。与您的逻辑不同的是提取组名的时间。从一开始就获得与P值相对应的组名。如果这种方法是错误的,我们只能帮助您部分加快该过程。谢谢您的理解。
g0 = pd.concat([names['g0'],pvalues['g0'],foldchanges['g0']],axis=1)
g0.columns = ['names','pvalues','foldchanges']
g0['group'] = 'g0'
g1 = pd.concat([names['g1'],pvalues['g1'],foldchanges['g1']],axis=1)
g1.columns = ['names','foldchanges']
g1['group'] = 'g1'
g2 = pd.concat([names['g2'],pvalues['g2'],foldchanges['g2']],axis=1)
g2.columns = ['names','foldchanges']
g2['group'] = 'g2'
g3 = pd.concat([names['g3'],pvalues['g3'],foldchanges['g3']],axis=1)
g3.columns = ['names','foldchanges']
g3['group'] = 'g3'
all_df = pd.concat([g0,g1,g2,g3],axis=0)
gb = all_df.groupby('names')['pvalues'].agg('min').reset_index()
all_df[(all_df['names'].isin(gb['names'])) & (all_df['pvalues'].isin(gb['pvalues']))]
names pvalues foldchanges group
1 Hspg2 0.004153 59.926384 g1
3 Serpinh1 0.007515 30.217304 g1
5 Lgr5 0.003352 15.884651 g1
7 Slc6a6 0.003947 99.277559 g1
8 Tpm1 0.000299 36.480099 g1
3 Fxyd3 0.000485 0.583842 g2
6 App 0.000566 23.006282 g2
0 Apoe 0.003422 11.763652 g3
1 Ltbp3 0.003203 25.222484 g3
9 Krt15 0.005134 80.433481 g3
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。