ある配列から別の1次元numpyアレイの要素の出現数を調べる – 配列aについて配列bの要素をカウント

Counting occurrences of elements of one array in another array – StackOverflow

行列数(row x column)が1億以下ならば,ブロードキャストは悪くない.今のようにユニーク列(カウントしたい要素が規定されたnumpy.ndarray)が小さいケースでは,ブロードキャストの方が速い.ただ,一般化された解法を考えれば,回答がリーズナブルチョイス.ブロードキャストする配列が大きくなればなる程,効率は悪化するので,バイナリサーチの方が効率的.ただ,「ソートされている」という強い条件が必要になるので,ソート済みじゃない場合は,必ずしも効率的とは言えない.Pandasが使えるなら,Pandasを用いた方が速い.

import numpy as np


def ucount(arr, u):
    idx = np.searchsorted(u, arr)
    idx[idx==len(u)] = 0
    mask = u[idx]==arr
    return np.bincount(idx[mask])


arr1 = np.array([1,2,6])
arr2 = np.array([2, 3, 6, 1, 2, 1, 2, 0, 2, 0])

print(ucount(arr2, arr1))
%timeit ucount(arr2, arr1)
print ((arr2 == arr1[:, None]).sum(1)) # (arr2[:, None] == arr1).sum(0)
%timeit (arr2 == arr1[:, None]).sum(1)

arr = np.concatenate([arr2]*100000)
%timeit ucount(arr, arr1)
%timeit (arr == arr1[:, None]).sum(1)

arr = np.concatenate([arr2]*1000000)
%timeit ucount(arr, arr1)
%timeit (arr == arr1[:, None]).sum(1)

arr = np.concatenate([arr2]*10000000)
%timeit ucount(arr, arr1)
%timeit (arr == arr1[:, None]).sum(1)

arr1 = np.unique(np.random.randint(1, 100000, size=10))
arr2 = np.random.randint(1, 100000, size=10000000)
%timeit ucount(arr2, arr1)
%timeit (arr2 == arr1[:, None]).sum(1)

arr1 = np.unique(np.random.randint(1, 100000, size=100))
arr2 = np.random.randint(1, 100000, size=1000000)
%timeit ucount(arr2, arr1)
%timeit (arr2 == arr1[:, None]).sum(1)

arr1 = np.unique(np.random.randint(1, 100000, size=1000))
arr2 = np.random.randint(1, 100000, size=100000)
%timeit ucount(arr2, arr1)
%timeit (arr2 == arr1[:, None]).sum(1)
[2 4 1]
100000 loops, best of 3: 5.07 µs per loop
[2 4 1]
100000 loops, best of 3: 3.91 µs per loop
100 loops, best of 3: 18.5 ms per loop
100 loops, best of 3: 6.02 ms per loop
10 loops, best of 3: 162 ms per loop
10 loops, best of 3: 61.4 ms per loop
1 loop, best of 3: 1.61 s per loop
1 loop, best of 3: 604 ms per loop

1 loop, best of 3: 322 ms per loop
1 loop, best of 3: 218 ms per loop
10 loops, best of 3: 59.3 ms per loop
10 loops, best of 3: 165 ms per loop
100 loops, best of 3: 8.05 ms per loop
10 loops, best of 3: 153 ms per loop

 
 
関連:
ある配列に含まれる任意の配列をみつける

ある配列を任意の配列の要素順にソート

あるアレイから任意のアレイに含まれる値のインデックスのみを取得

広告
カテゴリー: 未分類 パーマリンク

ある配列から別の1次元numpyアレイの要素の出現数を調べる – 配列aについて配列bの要素をカウント への3件のフィードバック

  1. ピンバック: データフレーム各行の連続したゼロをカウント | 粉末@それは風のように (日記)

  2. ピンバック: pandasデータフレーム列内のNaNに基づいて累積和をリセット – 任意の条件に基づいた範囲で累積和を求める | 粉末@それは風のように (日記)

  3. ピンバック: データフレーム列内の連続した値の和(任意長の範囲で合計) | 粉末@それは風のように (日記)

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google フォト

Google アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください