与熊猫的加权相关系数
Posted
技术标签:
【中文标题】与熊猫的加权相关系数【英文标题】:Weighted correlation coefficient with pandas 【发布时间】:2016-12-03 03:50:32 【问题描述】:有没有办法用熊猫计算加权相关系数?我看到R有这样的方法。 另外,我想获得相关性的 p 值。这我在 R 中也没有找到。 链接到***以获取有关加权相关性的说明:https://en.wikipedia.org/wiki/Pearson_product-moment_correlation_coefficient#Weighted_correlation_coefficient
【问题讨论】:
【参考方案1】:我不知道有任何 Python 包实现了这一点,但滚动您自己的实现应该相当简单。使用***文章的命名约定:
def m(x, w):
"""Weighted Mean"""
return np.sum(x * w) / np.sum(w)
def cov(x, y, w):
"""Weighted Covariance"""
return np.sum(w * (x - m(x, w)) * (y - m(y, w))) / np.sum(w)
def corr(x, y, w):
"""Weighted Correlation"""
return cov(x, y, w) / np.sqrt(cov(x, x, w) * cov(y, y, w))
我试图使上述函数尽可能地与***中的公式匹配,但有一些潜在的简化和性能改进。例如,正如@Alberto Garcia-Raboso 所指出的,m(x, w)
实际上只是np.average(x, weights=w)
,因此实际上不需要为它编写函数。
这些函数非常简单,只是进行计算。您可能需要考虑在进行计算之前将输入强制为数组,即x = np.asarray(x)
,因为如果传递了列表,这些函数将不起作用。还可以实施额外检查以验证所有输入是否具有相同的长度、非空值等。
示例用法:
# Initialize a DataFrame.
np.random.seed([3,1415])
n = 10**6
df = pd.DataFrame(
'x': np.random.choice(3, size=n),
'y': np.random.choice(4, size=n),
'w': np.random.random(size=n)
)
# Compute the correlation.
r = corr(df['x'], df['y'], df['w'])
有一个关于 p 值的讨论 here。看起来没有通用计算,这取决于您实际获得权重的方式。
【讨论】:
np.average
承认weights
参数,因此您可以将m(x, w)
定义为np.average(x, weights=w)
等等。
@AlbertoGarcia-Raboso:谢谢,我已经对此添加了评论。为了保持一致性,我保留了我的代码,以便它尽可能地匹配链接的***文章中的公式。
万一有人真正使用它,你也可以将cov(x, y, w)
的定义更改为return np.average((x - m(x, w)) * (y - m(y, w)), weights=w)
。
@RoobieNuby 为什么要使用 np.average 而不是将其他 m(*, *)
更改为使用 np.average
@DjangoTango 我的评论使用了also这个词。因此,在使用 Alberto Garcia-Raboso 对 m(x, w)
的定义之后,您还可以使用相同的内置函数定义协方差。事实上,您可以将cov(x, y, w)
定义为m((x - m(x, w)) * (y- m(y, w)), w)
。【参考方案2】:
statsmodels 包有一个implementation of weighted correlation。
【讨论】:
这行得通,但我发现的烦人的事情是,如果有 nan 值,statmodels 不想给出相关性。所以,首先我必须摆脱所有 nan 值。同样,当我传递一个数组并且只有某些列具有 nan 我希望其余列的相关性包括其他列与 nan 具有的行。但我想这是不可能的。也许我需要用平均值替换 NaN。然后它会工作 是的,nans 很烦人并且容易传播!但这真的很有意义:由您决定如何处理它们。我想你的方法听起来很合理,尽管它会减少一些相关性。如果数量不多,则不会有太大影响。以上是关于与熊猫的加权相关系数的主要内容,如果未能解决你的问题,请参考以下文章