微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

您将如何计算 100 万列 CSV 中两列的相关性?

如何解决您将如何计算 100 万列 CSV 中两列的相关性?

场景:

  • 我有一个 CSV 文件,第一列是“年龄”,还有一百万 其他列跨越。我想找到最多的列 与年龄相关。
  • 行数很少,比如不到 1000 行。
  • 这是用 Python 编写的更大解决方案的一部分,但这不一定是 Python。
  • 像大多数事情一样,我希望在代码可读性和性能之间取得平衡
  • 在下面的示例中,为简单起见,我只查看了一列。真正的解决方案可能会使用所有列的多处理。

我有下面的代码可以工作,但可以理解的是,将 CSV 存储为非常(非常!)宽的 Pandas 数据帧时速度会很慢。

如果是你,你会怎么做?

命令行:python mycode.py myfile.csv columnname-to-measure

import pandas as pd
from scipy import stats   
import os,sys

if __name__=="__main__":
    
    _DATAFILE = sys.argv[1]

    ##Sample tiny datafile
    
    #Age,m1,m2,m3
    #35,0.00234,0.1,1
    #30,0.0034,0.2,2
    #40,0.0013,0.3,4

    _MEASURE=sys.argv[2]

    print("Parsing file %s" %(_DATAFILE))
    
    df = pd.read_csv(_DATAFILE)
    print(f"Corellating {_MEASURE} with Age")
    all =df[['Age',_MEASURE]].copy()
    allna=all[all[_MEASURE].notna()]
    pearson_coef,p_value = stats.pearsonr( allna['Age'].values,allna[_MEASURE].values)
    print(pearson_coef,p_value)
   

解决方法

  1. 最好一次读取所有列并计算所有相关性,这样您就可以避免多次读取文件。或者,使用 parquet 等列式存储来存储您的文件,这样您就只能读取所需的列。查看 pandas.read_parquet 和 df.to_parquet。

  2. 使用 pandas 内置的相关方法往往会更快(底层 numpy 实现)。 https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.corr.html

  3. 我不认为多处理会提高太多速度,因为您的瓶颈是 csv IO 时间,而不是相关计算时间。要么一次性读取文件,要么使用镶木地板或某种方式。

,

对于您的用例来说,使用 pandas.DataFrame.corr 是否太慢?它会计算一堆不必要的相关性,但我会从那里开始。如果它太慢,那么您可以尝试numpy.corrcoef。我将这两个与您的示例数据进行了比较:

data = [[35,0.00234,0.1,1],[30,0.0034,0.2,2],[40,0.0013,0.3,4]]

df = pd.DataFrame(data,columns=['Age','m1','m2','m3'])
np_data = df.to_numpy()

在 Jupyter Lab 环境中使用 %timeit 魔法函数为它们计时:

%timeit df.corr()

产生 216 µs ± 24.3 µs per loop (mean ± std. dev. of 7 runs,1000 loops each)。尝试 numpy 路线:

%timeit np.corrcoef(np_data,rowvar=False)

产生 88 µs ± 1.4 µs per loop (mean ± std. dev. of 7 runs,10000 loops each)。所以 np.corrcoef 会快一点。

为了与 scipy.stats.pearsonr 进行比较,我将列迭代策略封装在一个函数中以对其进行计时:

def orig(df):
    for col in df.columns:
        pearson_coef,p_value = stats.pearsonr(df['Age'],df[col])

如果我们计时:

%timeit orig(df)

我们得到 450 µs ± 46.4 µs per loop (mean ± std. dev. of 7 runs,1000 loops each),因此 pandas.DataFrame.corrnumpy.corrcoef 都更快,尽管必须计算不必要的相关性。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。