7

假设我有一个pandas.DataFramedf. 的列df代表不同的个体,索引轴代表时间,因此 (i,j) 条目是个体 j 对时间段 i 的观察,我们可以假设所有数据都是float可能带有NaN值的类型。

就我而言,我有大约 14,000 列和几百行。

pandas.corr将返回 14,000 x 14,000 相关矩阵,它的时间性能对我的应用程序来说很好。

但我也想知道,对于每一对个体 (j_1, j_2),有多少非空观测值进入了相关性计算,因此我可以分离出数据覆盖率较差的相关性单元格。

我能想到的最好的方法如下:

not_null_locations = pandas.notnull(df).values.astype(int)
common_obs = pandas.DataFrame(not_null_locations.T.dot(not_null_locations),
                              columns=df.columns, index=df.columns)

内存占用和速度开始有点问题。

有没有更快的方法来获得常见的观察结果pandas

4

3 回答 3

3

你可以这样做,但需要 cythonize(否则要慢得多);但是内存占用应该更好(这给出了 nan 观察的数量,你给出了有效观察的数量,但很容易转换)

l = len(df.columns)
results = np.zeros((l,l))
mask = pd.isnull(df)
for i, ac in enumerate(df):
    for j, bc in enumerate(df):
           results[j,i] = (mask[i] & mask[j]).sum()
results = DataFrame(results,index=df.columns,columns=df.columns)
于 2013-08-14T14:44:56.797 回答
3

您实际上可以通过仅i + 1在嵌套循环中迭代(但不包括)来使@Jeff 的答案更快一点,并且由于相关性是对称的,您可以同时分配值。您还可以将mask[i]访问移到嵌套循环之外,这是一个微小的优化,但可能会为非常大的帧带来一些性能提升。

l = len(df.columns)
results = np.zeros((l,l))
mask = pd.isnull(df)
for i in range(l):
    maski = mask[i]
    for j in range(i + 1):
           results[i,j] = results[j,i] = (maski & mask[j]).sum()
results = DataFrame(results,index=df.columns,columns=df.columns)
于 2013-08-14T15:02:13.497 回答
-1

上面的两个答案都是错误的,一旦你必须传递非空值才能获得真值,并按列而不是按行进行比较。我设法通过以下方式获得了正确答案:

l = len(df.columns)
results = np.zeros((l,l))
mask = pd.notnull(df).values
for i in range(l):
    maski = mask[:,i]
    for j in range(i + 1):
        results[i,j] = results[j,i] = (maski & mask[:,j]).sum()
results = pd.DataFrame(results,index=df.columns,columns=df.columns)
于 2021-04-20T15:33:19.230 回答