2016-03-28 2 views
3

pixel bin/pixel bucket numpyの配列、つまりNの連続するピクセルのグループを、置き換えられたピクセルの合計である単一のピクセルで置き換えます。たとえば、値で開始します。私の知る限りでは、特にこれを行い何numpyの機能はありません(修正してくださいPythonのnumpyのN次元ピクセルビニング/バケットのリファレンス実装を作ってみましょう

bucket(x, bucket_size=2) 
= [1+3, 7+3, 2+9] 
= [4, 10, 11] 

x = np.array([1, 3, 7, 3, 2, 9]) 

2のバケットサイズで、これは変身します私が間違っていると私!)、私は頻繁に自分自身を転がす。 1D numpyのアレイでは、これは悪いことではありません。

import numpy as np 

def bucket(x, bucket_size): 
    return x.reshape(x.size // bucket_size, bucket_size).sum(axis=1) 

bucket_me = np.array([3, 4, 5, 5, 1, 3, 2, 3]) 
print(bucket(bucket_me, bucket_size=2)) #[ 7 10 4 5] 

...しかし、私は、多次元の場合のために簡単に混乱し、私は、この「簡単」に私自身のバギー、中途半端ソリューションを転がり終わります問題が何度も繰り返される。素敵なN次元のリファレンス実装を確立できれば、それが大好きです。

  • 好ましく関数呼び出しが(おそらくbucket(x, bucket_size=(2, 2, 3))のようなもの)を異なる軸に沿って異なるビンサイズを可能にする

  • 好ましくは、溶液が合理的に効率的である(再形成し、合計numpyの中でかなり速いです)

  • 配列が整数バケットにうまく分割されない場合のエッジ効果を処理するためのボーナスポイント。

  • ユーザが最初のビンエッジオフセットを選択できるようにするボーナスポイント。

Divakarによって示唆されるように、ここに私の希望の動作は、サンプル2-Dの場合には:

x = np.array([[1, 2, 3, 4], 
       [2, 3, 7, 9], 
       [8, 9, 1, 0], 
       [0, 0, 3, 4]]) 

bucket(x, bucket_size=(2, 2)) 
= [[1 + 2 + 2 + 3, 3 + 4 + 7 + 9], 
    [8 + 9 + 0 + 0, 1 + 0 + 3 + 4]] 
= [[8, 23], 
    [17, 8]] 

...うまくいけば、私は正しく私の算術演算をしました;)

答えて

1

x = array([[1, 2, 3, 4], 
      [2, 3, 7, 9], 
      [8, 9, 1, 0], 
      [0, 0, 3, 4]]) 

from numpy.lib.stride_tricks import as_strided  
def bucket(x,bucket_size): 
     x=np.ascontiguousarray(x) 
     oldshape=array(x.shape) 
     newshape=concatenate((oldshape//bucket_size,bucket_size)) 
     oldstrides=array(x.strides) 
     newstrides=concatenate((oldstrides*bucket_size,oldstrides)) 
     axis=tuple(range(x.ndim,2*x.ndim)) 
     return as_strided (x,newshape,newstrides).sum(axis) 

寸法は、xの対応する寸法に均等に分割されていない場合は、残りの要素が失われています。

検証:

In [9]: bucket(x,(2,2)) 
Out[9]: 
array([[ 8, 23], 
     [17, 8]]) 
+0

バケットの寸法は、アレイの対応する次元に分割しない場合、エラーが発生したと機能が全く実行されない - それはそうではないこと残りの要素は失われます。 (また、この回答は私が35分前に提案した方法と同じです:-)) –

+0

私のテストではエラーは発生しません。私はview_as_blocksの補集合としてそれを書いています。これは正確な除算を強制します。遅れて申し訳ありません、私は考えなければなりませんでした;) –

4

私はあなたができると思いますスキミングのview_as_blocksでほとんどの作業を行います。この関数はimplemented using as_stridedなので、非常に効率的です(ストライド情報を変更して配列を変形するだけです)。これはPython/NumPyで書かれているので、あなたがskimageをインストールしていなければ、いつでもコードをコピーすることができます。

この関数を適用した後は、再構成された配列のN個の末尾の軸を合計するだけで済みます(Nはbucket_sizeタプルの長さです)。例えば次に

from skimage.util import view_as_blocks 

def bucket(x, bucket_size): 
    blocks = view_as_blocks(x, bucket_size) 
    tup = tuple(range(-len(bucket_size), 0)) 
    return blocks.sum(axis=tup) 

:ここで新しいbucket()機能です

>>> x = np.array([1, 3, 7, 3, 2, 9]) 
>>> bucket(x, bucket_size=(2,)) 
array([ 4, 10, 11]) 

>>> x = np.array([[1, 2, 3, 4], 
        [2, 3, 7, 9], 
        [8, 9, 1, 0], 
        [0, 0, 3, 4]]) 

>>> bucket(x, bucket_size=(2, 2)) 
array([[ 8, 23], 
     [17, 8]]) 

>>> y = np.arange(6*6*6).reshape(6,6,6) 
>>> bucket(y, bucket_size=(2, 2, 3)) 
array([[[ 264, 300], 
     [ 408, 444], 
     [ 552, 588]], 

     [[1128, 1164], 
     [1272, 1308], 
     [1416, 1452]], 

     [[1992, 2028], 
     [2136, 2172], 
     [2280, 2316]]]) 
1

ndarray例のために、各軸に沿って異なるビンサイズを指定するには、そのように、それの各軸に沿ってnp.add.reduceatを使用し、繰り返し使用することができます -

def bucket(x, bin_size): 
    ndims = x.ndim 
    out = x.copy() 
    for i in range(ndims): 
     idx = np.append(0,np.cumsum(bin_size[i][:-1])) 
     out = np.add.reduceat(out,idx,axis=i) 
    return out 

サンプル実行 -

as_stridedからネイティブ
In [126]: x 
Out[126]: 
array([[165, 107, 133, 82, 199], 
     [ 35, 138, 91, 100, 207], 
     [ 75, 99, 40, 240, 208], 
     [166, 171, 78, 7, 141]]) 

In [127]: bucket(x, bin_size = [[2, 2],[3, 2]]) 
Out[127]: 
array([[669, 588], 
     [629, 596]]) 

# [2, 2] are the bin sizes along axis=0 
# [3, 2] are the bin sizes along axis=1 

# array([[165, 107, 133, | 82, 199], 
#  [ 35, 138, 91, | 100, 207], 
# ------------------------------------- 
#  [ 75, 99, 40, | 240, 208], 
#  [166, 171, 78, | 7, 141]]) 

In [128]: x[:2,:3].sum() 
Out[128]: 669 

In [129]: x[:2,3:].sum() 
Out[129]: 588 

In [130]: x[2:,:3].sum() 
Out[130]: 629 

In [131]: x[2:,3:].sum() 
Out[131]: 596 
関連する問題