ルークギブソン:
私は現在[COL]の2次元配列として格納されたバイナリ画像、[行]を有します。画像は線で2分割され、Iは1ライン上の全ての配列の値を設定します。
アレイの列を介して、現在、Iループ、配列[COL] [行]の値が1である。私は、をループから破る最初の行を見つけるために、カラム(上部に下部)の行をループ私は、その列の1から壊した行と行の上のすべての値を設定します。
残念ながら、1920x1080の画像について、これは3秒程度かかります。どのようにこれは、より効率的に達成することができましたか?
for x in range(len(image)):
col = image[x]
minY= -1
for y in range(len(col)):
if image[x][-y] != 0:
minY = y
break
if minY != -1:
under = [0] * minY
over = [1] * (len(col) - minY)
newCol = over + under
image[x] = newCol
前と下の写真の後...
norok2:
ここで、2D入力を必要とする方法のいくつ。彼らは正しい側に、正しい次元に取り組んでいるが、核となるアイデアが保持していることを確認するように調整する必要があるかもしれません。
- 使用
np.where()
してスライスと1つの薄暗いをループ:
import numpy as np
def side_fill_np(arr, value, flag):
rows, cols = arr.shape
idx = np.where(arr == flag)
for i in range(cols):
arr[idx[0][i]:, idx[1][i]] = value
return arr
- (あなたに似て、何とかクリーナー)フル明示的なループを使用して、しかしで加速
numba
import numba as nb
@nb.jit
def side_fill_nb(arr, value, flag):
rows, cols = arr.shape
for j in range(cols):
found = False
for i in range(rows):
if found:
arr[i, j] = value
elif arr[i, j] == flag:
found = True
我々は正しい結果を得ていることをテストするために、我々は、使用して、いくつかの入力を生成します。
def gen_data(shape):
rows, cols = shape
arr = np.zeros(shape, dtype=bool)
indexes = (np.random.randint(0, rows - 1, cols), np.arange(cols))
arr[indexes] = True
return arr
試験を読み取ります。
np.random.seed(0) # for reproducible results
arr = gen_data((10, 20))
print(arr.astype(int))
# [[0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# [0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0]
# [0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]
# [0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# [0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0]
# [1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1]
# [0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0]
# [0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0]
# [0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0]
# [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]
side_fill_np(arr, True, True)
print(arr.astype(int))
# [[0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# [0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0]
# [0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0]
# [0 1 1 1 0 1 0 1 0 0 0 0 0 1 0 0 0 0 1 0]
# [0 1 1 1 0 1 0 1 1 0 0 0 0 1 0 0 0 0 1 0]
# [1 1 1 1 0 1 1 1 1 0 0 0 0 1 0 0 0 0 1 1]
# [1 1 1 1 0 1 1 1 1 0 1 0 0 1 1 0 0 0 1 1]
# [1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 0 1 1]
# [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
# [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]]
今、約のタイミングについて。あなたの入力サイズ:
arr = gen_data((2000, 2000))
%timeit side_fill(arr, True, True)
# 1 loop, best of 3: 2.48 s per loop
%timeit side_fill_np(arr, True, True)
# 10 loops, best of 3: 52.6 ms per loop
%timeit side_fill_nb(arr, True, True)
# 100 loops, best of 3: 6.14 ms per loop
あなたが見ることができるように、(私は考えることができな限り多くのベクトル化された)numpyのアプローチで、あなたは約取得します。Numbaとの大きさのスピードアップの2件の受注は、あなたが約取得コードを加速させました。大きさはスピードアップの3桁。