python—如何处理在一百万列csv中计算两列的相关性?

qlvxas9a  于 2021-09-08  发布在  Java
关注(0)|答案(2)|浏览(539)

脚本:
我有一个csv,第一列是“年龄”,还有100万个其他列。我想找出与年龄最相关的栏目。
行数很低,比如说低于1000行。
这是用python编写的大型解决方案的一部分,但不一定是python。
像大多数事情一样,我希望在代码可读性和性能之间取得平衡
在下面的例子中,为了简单起见,我只看了一列。真正的解决方案可能会使用所有COL的多重处理。
我有下面的代码可以工作,但可以理解的是,csv存储为非常(非常!)宽。
如果是你,你会怎么做?
cmdline: 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)
6vl6ewon

6vl6ewon1#

正在使用 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()

给他们定时间 %timeit jupyter实验室环境中的神奇功能:

%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 ,我在函数中 Package 了一个列迭代策略,以对其进行计时:

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 速度更快,尽管必须计算不必要的相关性。

vom3gejh

vom3gejh2#

最好一次读取所有列并计算所有相关性,这样可以避免多次读取文件。或者,使用柱状存储(如Parquet)来存储文件,以便只能读取所需的列。看看PandasParquet地板和df.toParquet地板。
使用内置的关联方法往往更快(底层numpy实现)。https://pandas.pydata.org/docs/reference/api/pandas.dataframe.corr.html
我认为多重处理不会带来太多的速度,因为瓶颈是csv io时间,而不是相关计算时间。要么一次读取文件,要么使用Parquet或其他方式。

相关问题