【问题标题】:Pandas Correlation GroupbyPandas Correlation Groupby
【发布时间】:2015-05-13 08:40:06
【问题描述】:

假设我有一个类似于下面的数据框,我将如何获得 2 个特定列之间的相关性,然后按“ID”列分组?我相信 Pandas 'corr' 方法可以找到所有列之间的相关性。如果可能的话,我还想知道如何使用 .agg 函数(即 np.correlate)找到“groupby”相关性。

我有什么:

ID  Val1    Val2    OtherData   OtherData
A   5       4       x           x
A   4       5       x           x
A   6       6       x           x
B   4       1       x           x
B   8       2       x           x
B   7       9       x           x
C   4       8       x           x
C   5       5       x           x
C   2       1       x           x

我需要什么:

ID  Correlation_Val1_Val2
A   0.12
B   0.22
C   0.05

谢谢!

【问题讨论】:

    标签: python pandas group-by correlation


    【解决方案1】:

    一个更简单的解决方案:

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

    【讨论】:

      【解决方案2】:

      你几乎想通了所有的部分,只需将它们组合起来:

      >>> df.groupby('ID')[['Val1','Val2']].corr()
      
                   Val1      Val2
      ID                         
      A  Val1  1.000000  0.500000
         Val2  0.500000  1.000000
      B  Val1  1.000000  0.385727
         Val2  0.385727  1.000000
      

      在您的情况下,为每个 ID 打印 2x2 过于冗长。我没有看到打印标量相关性而不是整个矩阵的选项,但是如果您只有两个变量,您可以执行类似这样的简单操作:

      >>> df.groupby('ID')[['Val1','Val2']].corr().iloc[0::2,-1]
      
      ID       
      A   Val1    0.500000
      B   Val1    0.385727
      

      对于 3+ 个变量的更一般情况

      对于 3 个或更多变量,创建简洁的输出并不简单,但您可以执行以下操作:

      groups = list('Val1', 'Val2', 'Val3', 'Val4')
      df2 = pd.DataFrame()
      for i in range( len(groups)-1): 
          df2 = df2.append( df.groupby('ID')[groups].corr().stack()
                              .loc[:,groups[i],groups[i+1]:].reset_index() )
      
      df2.columns = ['ID', 'v1', 'v2', 'corr']
      df2.set_index(['ID','v1','v2']).sort_index()
      

      请注意,如果我们没有 groupby 元素,则可以直接使用 numpy 中的上三角函数或下三角函数。但由于存在该元素,据我所知,以更优雅的方式生成简洁的输出并不容易。

      【讨论】:

      • 如何将其更改为 'rolling_corr()' 以便每 10 天计算一次滚动相关性?
      • 这是一个很好的答案。事实上,对于这么简单的事情,不得不与.ilocs 混在一起,这是让我对 pandas 真正感到沮丧的事情之一。如果我想为科学数据建立一个大型处理管道,我最终会觉得一切都像牙膏一样。
      【解决方案3】:

      在上面的答案中;因为 ix 已被贬值,所以使用 iloc 来代替其他一些小的变化:

      df.groupby('ID')[['Val1','Val2']].corr().iloc[0::2][['Val2']] # to get pandas DataFrame
      

      df.groupby('ID')[['Val1','Val2']].corr().iloc[0::2]['Val2'] # to get pandas Series
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-21
        • 1970-01-01
        • 1970-01-01
        • 2017-04-06
        • 2017-03-16
        • 2017-12-22
        • 2018-10-02
        相关资源
        最近更新 更多