2017-07-21 1 views
2

次のようにIは、データフレーム内のクラスタ割り当てを類似性マトリックスに複数回(試験)に基づいてデータフレームのインデックスをクラスタ化し、保存:パンダ:データフレームで同じ値の計数インデックスペアワイズ発生

 trial 0 trial 1 trial 2 trial 3 
index 0 0  1  0  0 
index 1 0  1  1  0 
index 2 2  0  2  0 
index 3 1  2  2  1 

ノイズが付加され各試行の前に類似性マトリクスに割り当てることにより、クラスタ割当が非決定論的である(したがって、各試行の割当の差異)。したがって、明確にするには:各試行は完全なクラスタリング実行に対応し、値はその試行のクラスタに対応します。

上記の例では、同じクラスタで3回、index 0index 1が共起しています。

私がしたいことはそうのような共起行列である:各値は、インデックスがすべての試験間で共起するクラスタの数に対応し

 index 0 index 1 index 2 index 3 
index 0 4  3  1  0 
index 1 3  4  1  0 
index 2 1  1  4  1 
index 3 0  0  1  4 

パンダでこれを行う効率的な方法はありますか?私は簡単にループでそれを管理することができますが、私の試行データフレームには数千の指標と試練があります。

+1

インデックス0とインデックス1はどのように3回共起するのですか? –

+0

@coldspeedこれらは同じクラスタに3回割り当てられます(trial0のcluster0に割り当てられ、trial1のcluster1とtrial3のcluster0に割り当てられます) – duncster94

答えて

1

私は線形代数のビットでそれを行う方法を考え出しました。

最初に、試行行列は、各数に対応する合計に分解されます(実装では不要ですが、数は数学的に式を定式化するためには1から始まる必要があります)。

ある:

 trial 0 trial 1 trial 2 trial 3 
index 0 0  1  0  0 
index 1 0  1  1  0 
index 2 2  0  2  0 
index 3 1  2  2  1 

は、以下のように分解される(インクリメント)

 trial 0 trial 1 trial 2 trial 3 
index 0 1  2  1  1 
index 1 1  2  2  1 
index 2 3  1  3  1 
index 3 2  3  3  2 

、次のようになる。

T = 1 0 1 1 + 2 * 0 1 0 0 + 3 * 0 0 0 0 
    1 0 0 1   0 1 1 0  0 0 0 0 
    0 1 0 1   0 0 0 0  1 0 1 0 
    0 0 0 0   1 0 0 1  0 1 1 0 

そして各(正規化)成分行列が乗算されますその転置によって合計される:

C1*C1.T/1 + C2*C2.T/2 + C3*C3.T/3 

ここで、Ciは、クラスタ番号iに対応するTのマトリックス成分です。

この合計は、結果の共起行列です。以下は、上記の例の実装と結果である:

test = pd.DataFrame(np.array([[0, 1, 0, 0], 
           [0, 1, 1, 0], 
           [2, 0, 2, 0], 
           [1, 2, 2, 1]]), 
        columns = ['trial 1', 'trial 2', 'trial 3', 'trial 4']) 
test_val = test.values 

# Base matrix that will be added to. 
curr_mat = np.zeros((test_val.shape[0], test_val.shape[0])) 

# Max index of matrix components (i.e. max_val + 1 is number of clusters/matrix components) 
max_val = np.max(test_val) 

for n_clus in range(max_val + 1): 

    # Extract component matrix corresponding to current iteration. 
    clus_mem = (test_val == n_clus).astype(int) 
    curr_mat += np.dot(clus_mem, clus_mem.T) 

res = pd.DataFrame(curr_mat, index=test.index, columns=test.index) 

結果で:

  index 0 index 1 index 2 index 3 
index 0  4  3  1  0 
index 1  3  4  1  0 
index 2  1  1  4  1 
index 3  0  0  1  4 

は、残念ながら、私はforループを使用する必要がありましたが、反復回数は現在のクラスタの数だけありますnumpyの効率的な配列操作を利用しています。

+0

'(test_val == n_clus).astype(np.float32)'です。したがって、同じdtypeで 'curr_mat'を初期化してください。 – Divakar

1

ここでは、列だけをループする必要があるソリューションです。

res = sum(df[c].transform(lambda x: x == df[c]) for c in df.columns)

しかし、あなたのデータは、ループやグラフが速くなってしまうかもしれ使用して、かなりまばらである場合。

関連する問題