如何在Pandas数据框的列中找到一组值之间的相关性

7

I have a dataframe df:

ID    Var1     Var2
1     1.2        4
1     2.1        6
1     3.0        7
2     1.3        8
2     2.1        9
2     3.2        13

我希望找出每个ID之间Var1Var2的皮尔逊相关系数值。
因此,结果应该如下所示:
ID    Corr_Coef
1     0.98198
2     0.97073

更新:

必须确保所有变量的列都是intfloat类型。


如果您最后得到的数据框只有ID Var1为1.0,那么您的输入数据框只有Var1,您正在对其进行何种相关性分析?请检查您的输入数据框。 - Scott Boston
df就是我上面展示的内容。我已经检查过了。可能是Python版本的问题?例如,当我使用其他groupby函数(如count())时,结果中会得到两列Var1和Var2。 - BKS
不太可能。你有其他非常奇怪的问题发生了。 - Scott Boston
我解决了。由于某种原因,它将Var2读取为字符串。所以我只需将该列的类型更改为整数即可解决问题。 - BKS
你可能想要回去重新审视一下Brad的解决方案。 - Scott Boston
4个回答

15

您可以使用.corrwith来获取所需的输出格式:

corrs = (df[['Var1', 'ID']]
        .groupby('ID')
        .corrwith(df.Var2)
        .rename(columns={'Var1' : 'Corr_Coef'}))

print(corrs)
    Corr_Coef
ID           
1     0.98198
2     0.97073

普遍解:

import numpy as np

def groupby_coef(df, col1, col2, on_index=True, squeeze=True, name='coef',
                 keys=None, **kwargs):
    """Grouped correlation coefficient between two columns

    Flat result structure in contrast to `groupby.corr()`.

    Parameters
    ==========
    df : DataFrame
    col1 & col2: str
        Columns for which to calculate correlation coefs
    on_index : bool, default True
        Specify whether you're grouping on index
    squeeze : bool, default True
        True -> Series; False -> DataFrame
    name : str, default 'coef'
        Name of DataFrame column if squeeze == True
    keys : column label or list of column labels / arrays
        Passed to `pd.DataFrame.set_index`
    **kwargs :
        Passed to `pd.DataFrame.groupby`
    """

    # If we are grouping on something other than the index, then
    #     set as index first to avoid hierarchical result.
    # Kludgy, but safer than trying to infer.
    if not on_index:
        df = df.set_index(keys=keys)
        if not kwargs:
            # Assume we're grouping on 0th level of index
            kwargs = {'level': 0}
    grouped = df[[col1]].groupby(**kwargs)
    res = grouped.corrwith(df[col2])
    res.columns = [name]
    if squeeze:
        res = np.squeeze(res)
    return res

示例:

df_1 = pd.DataFrame(np.random.randn(10, 2), 
                    index=[1]*5 + [2]*5).add_prefix('var')
df_2 = df_1.reset_index().rename(columns={'index': 'var2'})

print(groupby_coef(df_1, 'var0', 'var1', level=0))
1    7.424e-18
2   -9.481e-19
Name: coef, dtype: float64

print(groupby_coef(df_2, col1='var0', col2='var1', 
                   on_index=False, keys='var2'))
var2
1    7.424e-18
2   -9.481e-19
Name: coef, dtype: float64

我在使用 .corrwith 时一直遇到一个错误,但我不理解 `/usr/local/lib/python2.7/dist-packages/pandas/core/groupby.pyc in corrwith(self, other, axis, drop)/usr/local/lib/python2.7/dist-packages/pandas/core/groupby.pyc in wrapper(*args, **kwargs) 590 *args, **kwargs) 591 except (AttributeError): --> 592 raise ValueError 593 594 return wrapperValueError:` - BKS
import pandas --> pandas.__version__ 会给你什么信息?另外,除了这里给出的3列之外,你的数据框中还有其他列吗? - Brad Solomon
没有其他列。但是即使有,df[['Var1', 'ID']]也应该将它们删除吗?另外,我正在使用pandas 0.19.2。 - BKS
回答你的问题——是的。我有点困惑,但在切换到0.19.2后以无问题运行了上述脚本。我想这可能与Python 2.x v 3.x有关,请试一下@Scott的答案如果适用的话就接受吧。 - Brad Solomon
我成功地使用了Brad的解决方案。然而,我也在使用Python 3。 - Scott Boston
我无法让两者同时工作。可能是因为我正在使用Python 2.7,而不是Python 3的原因。 - BKS

10
df.groupby('ID').corr()

输出:

             Var1      Var2
ID                         
1  Var1  1.000000  0.981981
   Var2  0.981981  1.000000
2  Var1  1.000000  0.970725
   Var2  0.970725  1.000000

使用OP输出格式。

df_out = df.groupby('ID').corr()
(df_out[~df_out['Var1'].eq(1)]
          .reset_index(1, drop=True)['Var1']
          .rename('Corr_Coef')
          .reset_index())

输出:

   ID  Corr_Coef
0   1   0.981981
1   2   0.970725

当我使用 df.groupby('ID').corr() 时,它只是将 Var1 与自身进行比较...因此我只会得到一个由1填充的列输出。 - BKS
我不太理解你的回答。df_out是什么?是从.corr函数得到的输出数据框吗?因为我得到的只是随机答案。 - BKS
df_out = df.groupby('ID').corr() df_out = df按照'ID'分组后进行相关性计算。 - Scott Boston
好的,我理解得没错。这就让我们回到了最初的评论。我会收到一个错误提示,因为corr()函数只会将Var1与自身进行比较,而不考虑Var2。输出矩阵仅包含Var1。 - BKS
我会在我的回答中发布结果矩阵。 - BKS
显示剩余2条评论

0

由于这两个解决方案对我都不起作用,我将发布一个允许在python3中计算不同组中一列之间相关性的解决方案。希望这能解决@BKS遇到的同样问题。

data = df[['date', 'group_id', 'var1']]
data_new = data.set_index(['date', 'group_id']).unstack(['group_id'])
final_df = pd.DataFrame(data_new.to_numpy(), columns=data_new.columns)
dfCorr = final_df.corr()

0

简单的解决方案:

df.groupby('ID').corr().unstack().iloc[:,1]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接