パンダのデータフレームでユニオン(ジャッカードのインデックス)の交差を計算します
Aug 22 2020
私は次のようなデータフレームを持っています:
animal ids
cat 1,3,4
dog 1,2,4
hamster 5
dolphin 3,5
データフレームは非常に大きく、8万行を超え、ids列には数千を超えるIDが含まれている可能性があります。特定の行のIDは、コンマ区切りの文字列で一意になります。
Jaccardのインデックスを計算するデータフレームを構築したいと思います。つまり、動物の列の各項目と、和集合のids列の項目の共通部分です。
したがって、猫と犬を見ると、和集合は2(id 1と4)であり、和集合は4(id 1、2、3、4)であるため、Jaccardのインデックスは2/4 = 0.5です。この形式のデータセットがあると便利です。
cat dog hamster dolphin
cat 1 0.5 0 0.25
dog 0.5 1 0 0
hamster 0 0 1 0.5
dolphin 0.25 0 0.5 1
これは、動物の名前として行インデックスを使用することを意味します。これにより、関連するjaccardのインデックスを次のようにすばやく見つけることができます。
cat_dog_ji = df_new['cat']['dog']
回答
5 user3483203 Aug 22 2020 at 19:04
ここでstr.get_dummies
といくつかのscipy
ツールを使用できます。
from scipy.spatial import distance
u = df["ids"].str.get_dummies(",")
j = distance.pdist(u, "jaccard")
k = df["animal"].to_numpy()
pd.DataFrame(1 - distance.squareform(j), index=k, columns=k)
cat dog hamster dolphin
cat 1.00 0.5 0.0 0.25
dog 0.50 1.0 0.0 0.00
hamster 0.00 0.0 1.0 0.50
dolphin 0.25 0.0 0.5 1.00
3 ShubhamSharma Aug 22 2020 at 18:38
使用する:
d = df.assign(key=1, ids=df['ids'].str.split(','))
d = d.merge(d, on='key', suffixes=['', '_r'])
i = [np.intersect1d(*x).size / np.union1d(*x).size for x in zip(d['ids'], d['ids_r'])]
d = pd.crosstab(d['animal'], d['animal_r'], i, aggfunc='first').rename_axis(index=None, columns=None)
詳細:
使用するDataFrame.assign一時的な列を作成しkey
、使用するSeries.str.split列にしますids
。次に、を使用DataFrame.mergeして、データフレームd
をそれ自体に基づく列とマージしますkey
(基本的にクロス結合)。
print(d)
animal ids key animal_r ids_r
0 cat [1, 3, 4] 1 cat [1, 3, 4]
1 cat [1, 3, 4] 1 dog [1, 2, 4]
2 cat [1, 3, 4] 1 hamster [5]
3 cat [1, 3, 4] 1 dolphin [3, 5]
4 dog [1, 2, 4] 1 cat [1, 3, 4]
5 dog [1, 2, 4] 1 dog [1, 2, 4]
6 dog [1, 2, 4] 1 hamster [5]
7 dog [1, 2, 4] 1 dolphin [3, 5]
8 hamster [5] 1 cat [1, 3, 4]
9 hamster [5] 1 dog [1, 2, 4]
10 hamster [5] 1 hamster [5]
11 hamster [5] 1 dolphin [3, 5]
12 dolphin [3, 5] 1 cat [1, 3, 4]
13 dolphin [3, 5] 1 dog [1, 2, 4]
14 dolphin [3, 5] 1 hamster [5]
15 dolphin [3, 5] 1 dolphin [3, 5]
内部リスト内包表記np.interset1dとともに使用してnp.union1d、Jaccard's
インデックスを計算します。
print(i)
[1.0, 0.5, 0.0, 0.25, 0.5, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.5, 0.25, 0.0, 0.5, 1.0]
最後に、を使用pd.crosstabして単純なクロス集計を作成し、目的の形式で結果を取得します。
print(d)
cat dog dolphin hamster
cat 1.00 0.5 0.25 0.0
dog 0.50 1.0 0.00 0.0
dolphin 0.25 0.0 1.00 0.5
hamster 0.00 0.0 0.50 1.0