问题描述
当第三列满足某些条件时,我试图找到一种方法来获取数据框中两列之间的人员相关性和 p 值。
df =
BucketID | 强度 | BW25113 |
---|---|---|
825.326 | 3459870 | 0.5 |
825.326 | 8923429 | 0.95 |
734.321 | 12124 | 0.4 |
734.321 | 2387499 | 0.3 |
我最初尝试使用 pd.Series.corr()
函数进行一些操作,该函数速度非常快,并且执行我想要的操作以获得最终输出:
bio1 = df.columns[1:].tolist()
pcorrs2 = [s + '_Corr' for s in bio1]
coldict2 = dict(zip(bios,pcorrs2))
coldict2
df2 = df.groupby('BucketID')[bio1].corr(method = 'pearson').unstack()['Intensity'].reset_index().rename(columns = coldict2)
df3 = pd.melt(df2,id_vars = 'BucketID',var_name = 'Org',value_name = 'correlation')
df3['Org'] = df3.Org.apply(lambda x: x.rstrip('_corr'))
df3
这给了我(大部分)想要的表:
BucketID | 组织 | 相关性 |
---|---|---|
734.321 | 强度 | 1.0 |
825.326 | 强度 | 1.0 |
734.321 | BW25113 | -1.0 |
825.326 | BW25113 | 1.0 |
这适用于给我个人相关性而不是 p 值,这将有助于确定相关性的相关性。
有没有办法以这种方式获取与 pd.Series.corr()
关联的 p 值,或者使用 scipy.stats.pearsonr
迭代每个 BucketID 的数据帧的版本会更有效吗?我尝试过这种口味的东西,但速度非常慢(几十分钟而不是几秒钟)。
预先感谢您的帮助和/或评论。
解决方法
您可以在数据帧上使用 scipy.stats.pearsonr
,如下所示:
df = pd.DataFrame({'col1': [1,2,3,4,5,6,7,8,9,10],'col2': [1,12]})
import scipy
scipy.stats.pearsonr(df['col1'],df['col2'])
产生一个元组,第一个是相关性,第二个值是 p 值。
(0.9049484650760702,0.00031797789083818853)
更新
要以编程方式为组执行此操作,您可以 groupby() 然后遍历组...
df = pd.DataFrame({'group': ['A','A','B','B'],'col1': [1,12]})
for group_name,group_data in df.groupby('group'):
print(group_name,scipy.stats.pearsonr(group_data['col1'],group_data['col2']))
结果...
A (0.9817469600192116,0.0029521879612042588)
B (0.8648495371134326,0.05841898744667266)
这些也可以存储在新的 df results
results = pd.DataFrame()
for group_name,group_data in df.groupby('group'):
correlation,p_value = scipy.stats.pearsonr(group_data['col1'],group_data['col2'])
results = results.append({'group': group_name,'corr': correlation,'p_value': p_value},ignore_index=True)