2013-08-14 5 views
6

pandas.DataFramedfとします。 dfの列は異なる個体を表し、インデックス軸は時間を表すので、(i、j)項目は期間iの個体jの所見であり、すべてfloat型の可能性があり、値はNaNであると仮定できます。Python Pandasの相関行列エントリの一般的な観測回数を見るための速い方法

私の場合、私は約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の一般的な観察結果を得るための方法はありますか?

+2

、直接答えていませんが、あなたは「十分に良い」を与えることが – Jeff

+0

に答えますそれはすばらしい提案ですが、私はPandasバージョン0.8.0を必要とするプロダクションシステムで作業しています。新しいバージョンでは 'min_periods'が追加されたようです。古いバージョンについては何もできません。恐らく。 – ely

+0

あなたは* linux上であればコード内に*追加することができます(かなり簡単です).....その唯一のいくつかの行の変更(もちろん 'production'はおそらくこれを排除します) – Jeff

答えて

3

これを行うことはできますが、cythonizeする必要があります(それ以外の場合は非常に遅くなります)。しかし メモリフットプリントが良いはずです(これはナンの観測数を与え、あなたは有効な観測数が、簡単にコンバーチブルを与える)

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) 
3

あなたが実際には(まで反復することによって少し速くジェフの答え@作ることができますネストされたループ内にはi + 1が含まれています)。また、相関が対称であるため、同時に値を割り当てることができます。また、ネストされたループの外部にある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) 
あなたが部分的に(例えばそのあなたが観測値の最小数はいる必要がカットオフCORRに `` min_periods``を渡すことによって、この問題を解決することができます
関連する問題