リストのパンダの列にリストの交差点の長さを数えます

ミゲルJiahao王:

私は以下のような、独特のランダムな整数のリストやリストの列を持つデータフレームを持っています。

>>> panel
    [1, 10, 9, 5, 6]

>>> df
       col1 
    0  [1, 5]
    1  [2, 3, 4]
    2  [9, 10, 6]

私が持っていると思います出力は、重なりの長さpanelとデータフレーム内の個々のリスト:

>>> result
       col1        res
    0  [1, 5]      2
    1  [2, 3, 4]   0
    2  [9, 10, 6]  3

現在、私は使用していますapply機能を、より高速な方法がある場合、私は、各パネルについて、この作業を通じてパネルとループの多くを作成する必要があるので、私は、思っていました。

# My version right now
def cntOverlap(panel, series):
    # Typically the lists inside df will be much shorter than panel, 
    # so I think the fastest way would be converting the panel into a set 
    # and loop through the lists within the dataframe

    return sum(1 if x in panel for x in series)
    #return len(np.setxor1d(list(panel), series))
    #return len(panel.difference(series))


for i, panel in enumerate(list_of_panels):
    panel = set(panel)
    df[f"panel_{i}"] = df["col1"].apply(lambda x: cntOverlap(panel, x))

Divkr:

行あたりの可変長データのおかげで、我々は(明示的または暗黙的にすなわちボンネットの下)のPython内に留まる反復処理する必要があります。しかし、私たちは繰り返しごとに計算が最小化されたレベルに最適化することができます。その哲学と一緒に行く、ここで配列割り当てと、いくつかのマスキングとの1です -

# l is input list of unique random integers
s = df.col1
max_num = 10 # max number in df, if not known use : max(max(s))
map_ar = np.zeros(max_num+1, dtype=bool)
map_ar[l] = 1
df['res'] = [map_ar[v].sum() for v in s]

あるいは2次元アレイ割り当てをさらにごと反復-計算を最小限に抑えます -

map_ar = np.zeros((len(df),max_num+1), dtype=bool)
map_ar[:,l] = 1
for i,v in enumerate(s):
    map_ar[i,v] = 0
df['res'] = len(l)-map_ar.sum(1)

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=10384&siteId=1