這解決方案概括爲n
讓我們來重述一下這個pro瑕疵爲「找到索引列表」。
我們正在尋找一切形式的二維數組索引的
array[i[0], i[1], i[2], ..., i[n-1]]
讓n = arr.ndim
哪裏i
是形狀(n, k)
陣列,每個的i[j]
可以是一個:
- 相同的索引重複n次,
ri[j] = [j, ..., j]
- 的正向序列,
fi = [0, 1, ..., k-1]
- 向後序列,
bi = [k-1, ..., 1, 0]
隨着每個序列的形式^(ri)*(fi)(fi|bi|ri)*$
的要求(使用正則表達式來概括它)。這是因爲:
- 必須有至少一個
fi
因此,「行」是不會重複選擇一個點
- 沒有
bi
š來之前fi
S,以避免得到扭轉線
def product_slices(n):
for i in range(n):
yield (
np.index_exp[np.newaxis] * i +
np.index_exp[:] +
np.index_exp[np.newaxis] * (n - i - 1)
)
def get_lines(n, k):
"""
Returns:
index (tuple): an object suitable for advanced indexing to get all possible lines
mask (ndarray): a boolean mask to apply to the result of the above
"""
fi = np.arange(k)
bi = fi[::-1]
ri = fi[:,None].repeat(k, axis=1)
all_i = np.concatenate((fi[None], bi[None], ri), axis=0)
# inedx which look up every possible line, some of which are not valid
index = tuple(all_i[s] for s in product_slices(n))
# We incrementally allow lines that start with some number of `ri`s, and an `fi`
# [0] here means we chose fi for that index
# [2:] here means we chose an ri for that index
mask = np.zeros((all_i.shape[0],)*n, dtype=np.bool)
sl = np.index_exp[0]
for i in range(n):
mask[sl] = True
sl = np.index_exp[2:] + sl
return index, mask
應用到你的例子:
# construct your example array
n = 3
k = 3
data = np.arange(k**n).reshape((k,)*n)
# apply my index_creating function
index, mask = get_lines(n, k)
# apply the index to your array
lines = data[index][mask]
print(lines)
array([[ 0, 13, 26],
[ 2, 13, 24],
[ 0, 12, 24],
[ 1, 13, 25],
[ 2, 14, 26],
[ 6, 13, 20],
[ 8, 13, 18],
[ 6, 12, 18],
[ 7, 13, 19],
[ 8, 14, 20],
[ 0, 10, 20],
[ 2, 10, 18],
[ 0, 9, 18],
[ 1, 10, 19],
[ 2, 11, 20],
[ 3, 13, 23],
[ 5, 13, 21],
[ 3, 12, 21],
[ 4, 13, 22],
[ 5, 14, 23],
[ 6, 16, 26],
[ 8, 16, 24],
[ 6, 15, 24],
[ 7, 16, 25],
[ 8, 17, 26],
[ 0, 4, 8],
[ 2, 4, 6],
[ 0, 3, 6],
[ 1, 4, 7],
[ 2, 5, 8],
[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 13, 17],
[11, 13, 15],
[ 9, 12, 15],
[10, 13, 16],
[11, 14, 17],
[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17],
[18, 22, 26],
[20, 22, 24],
[18, 21, 24],
[19, 22, 25],
[20, 23, 26],
[18, 19, 20],
[21, 22, 23],
[24, 25, 26]])
另一套很好的測試數據是np.moveaxis(np.indices((k,)*n), 0, -1)
,這給出了一個數組,其中的每個值都是自己的索引
我之前解決了這個問題實施higher dimensional tic-tac-toe
2個高亮塊對於2D對角線有什麼意義?中央對角線將有3個項目;你在同一個元組中包含了反對角線,但是不知怎麼分開了。你是否也對偏移對角線感興趣? – hpaulj
你想生成'(0,1,2)'和'(2,1,0)'嗎? – Eric
你想實現[this](http://ericwieser.me/games/4d/)嗎? – Eric