2016-07-19 10 views
2

タイトルには、ある条件の下でデータフレームの各列のペアに関数を適用しようとしています。私はこれを説明しようとします。私のDFの形式のものである:Pandas:制約の下で各列のペアに関数を適用します。

Code | 14 | 17 | 19 | ... 
w1 | 0 | 5 | 3 | ... 
w2 | 2 | 5 | 4 | ... 
w3 | 0 | 0 | 5 | ... 

コードは、矩形グリッドに決定された位置に対応し、WSが異なる単語です。私は、列の各列の間にコサイン類似度測度を適用したいだけです(EDITED!)ペアの列のいずれかの項目の合計がth30より大きい場合はです。

所望の出力のようなものであろう:

 | [14,17] | [14,19] | [14,...] | [17,19] | ... 
Sim |cs(14,17) |cs(14,19) |cs(14,...) |cs(17,19)..| ... 

CSはカラムの各ペアのためのコサイン類似度の結果です。 これを行うには適切な方法はありますか?

すべてのヘルプはあなた がscipy.spatial.distance.cdistを使用することができ、入力の2つのコレクションから、各ペアにコサインメトリックを適用するには

+0

シリーズ(14,17)'や 'CS(14,19)'などを生み出します5より大きい '14'列。何か試しましたか?失敗したコードとサンプルを提供してください。 – danielhadar

+0

こんにちは@ダニエルハダール。実際には今まで私は手作業で計算していません。私は、ベクトルの方法で、つまり列にループを書くことなく、列の各ペアに関数を適用する方法(この場合はコサイン類似度ですが、より多くの関数を適用します)があるかどうかを尋ねています。最後のdfのビルドは、結果をよりよく視覚化することだけですが、重要ではありません。 –

答えて

3

:-)いただければ幸いです。これは、ダブルPythonループを使用して よりはるかに高速です。

1つのコレクションをすべてdfの列とします。他のコレクションは、合計が5以上である列のみとします:

import pandas as pd 
df = pd.DataFrame({'14':[0,2,0], '17':[5,5,0], '19':[3,4,5]}) 
mask = df.sum(axis=0) > 5 
df2 = df.loc[:, mask] 

その後、すべてのコサイン類似点がcdistに一度のコールで計算することができます。値がでラップでき

import scipy.spatial.distance as SSD 
values = SSD.cdist(df2.T, df.T, metric='cosine') 
# array([[ 2.92893219e-01, 1.11022302e-16, 3.00000000e-01], 
#  [ 4.34314575e-01, 3.00000000e-01, 1.11022302e-16]]) 

新しいデータフレームと作り直さ:

result = pd.DataFrame(values, columns=df.columns, index=df2.columns) 
result = result.stack() 

import pandas as pd 
import scipy.spatial.distance as SSD 
df = pd.DataFrame({'14':[0,2,0], '17':[5,5,0], '19':[3,4,5]}) 
mask = df.sum(axis=0) > 5 
df2 = df.loc[:, mask] 
values = SSD.cdist(df2.T, df.T, metric='cosine') 
result = pd.DataFrame(values, columns=df.columns, index=df2.columns) 
result = result.stack() 
mask = result.index.get_level_values(0) != result.index.get_level_values(1) 
result = result.loc[mask] 
print(result) 
何の項目がでありませんので

は、私はまっすぐにそれを取得していた場合、あなたは `CSを望んでいないだろう

17 14 0.292893 
    19 0.300000 
19 14 0.434315 
    17 0.300000 
関連する問題