隣接セルの合計(コンボリューション)

Python: how to reshape a dataframe by summing neighbour cells? – StackOverflow

隣接セルの足し合わせは要はコンボリューション(2Dのコンボリューションを行う方法としては、「scipy.ndimage.convolve」と「scipy.signal.convolve」があるが、関連に示す様に効率が全然違う(N数が大きくなると20倍以上)ので使い分けが重要;同様のケースでは「scipy.ndimage.convolve」がリーズナブルチョイス).それとは別にFlat Indexing(Linear Indexing)という手もある.

import io
import numpy as np
import pandas as pd
from scipy import ndimage
from scipy import signal


def sum_cells(arr, R=3, C=3, n=1):
    r, c = arr.shape
    idx = (
        ((np.arange(R)*c)[:, None] + np.arange(C)).ravel()
        + np.arange(0, c-n, C-n)[:, None]
        + np.arange(0, r-n, R-n)[:, None, None]*c
    )
    return arr.flat[idx].sum(-1)


strings = """        0   1   2   3   4
     0  8   3   2   2   5
     1  5   8   1   5   6
     2  1   9   1   4   2
     3  0   7   7   6   9
     4  5   8   7   0   9
     5  0   3   9   9   4
     6  7   7   8   5   4"""

df = pd.read_csv(io.StringIO(strings), sep='\s+')
arr = df.values

kernel = np.ones((3, 3), dtype=np.int8)
res1 = pd.DataFrame(signal.convolve(arr, kernel, 'same')[1::2, 1::2])
print(res1, end='\n\n')
%timeit kernel = np.ones((3, 3), dtype=np.int8);res1 = pd.DataFrame(signal.convolve(arr, kernel, 'same')[1::2, 1::2])

res2 = pd.DataFrame(ndimage.convolve(arr, kernel, mode='constant')[1::2, 1::2])
print(res2, end='\n\n')
%timeit kernel = np.ones((3, 3), dtype=np.int8);res2 = pd.DataFrame(ndimage.convolve(arr, kernel, mode='constant')[1::2, 1::2])

res3 = pd.DataFrame(sum_cells(arr))
print(res3, end='\n\n')
%timeit res3 = pd.DataFrame(sum_cells(arr))
    0   1
0  38  28
1  45  45
2  54  55

10000 loops, best of 3: 138 µs per loop
    0   1
0  38  28
1  45  45
2  54  55

10000 loops, best of 3: 117 µs per loop
    0   1
0  38  28
1  45  45
2  54  55

10000 loops, best of 3: 93.1 µs per loop

 
 
関連:
隣接カウント

隣接セルの合計(コンボリューション)

2D配列(numpy.ndarray)の隣接要素をグループ化(クラスタ化)

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

コメントを残す

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

WordPress.com ロゴ

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

Google フォト

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

Twitter 画像

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

Facebook の写真

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

%s と連携中