numpy逻辑运算问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了numpy逻辑运算问题相关的知识,希望对你有一定的参考价值。
我在创造一个游戏。在游戏中,我有一个以0开头的numpy数组(正方形)。玩家通过将指定的整数添加到某个位置来填充数组。玩家可以通过填充整个行,列,对角线或反对角线(?)来获得游戏。目前这是我检查游戏成功的功能。
我有两个问题:1。我希望该功能检查所有玩家是否成功并返回一个元组(即(如果玩家2已赢)则返回(True,2)而不是一次一个。游戏的运作方式,永远不会有两名球员获胜,所以这不是问题。我将列出所有玩家的名单(即4名玩家的[1,2,3,4])我可以传递给该功能。 2.我不想要“for”循环,因为我想在很多次迭代中执行此操作。
我一直在努力与numpy中的逻辑运算符,但我不想将其更改为列表或其他任何东西。
def check_success(gm,player): #gm is game array
for i in range(len(gm)):
if (not any(gm[i]-player)) or (not any(gm[:,i]-player)):
return True
if (not any(np.diag(gm)-player)) or (not any(np.diag(np.fliplr(gm))-player)):
return True
return False
注意:我怀疑没有for循环就无法解决问题#1。如果是这种情况,我更喜欢问题#2解决了。我总是可以多次运行该功能,因为玩家的数量肯定会比gm的大小少得多。
答案
更新:优化的代码和基准:
计时
>>> stress_test(4, 1000, 2, 0, 0)
OP : 0.322599 ms
pp0 : 0.451822 ms
pp1 : 0.140838 ms
>>>
>>> stress_test(10, 1000, 4)
OP : 1.051070 ms
pp0 : 0.425230 ms
pp1 : 0.166876 ms
码
import numpy as np
def f_OP(board, p):
for cp in range(1, p+1):
if check_success(board, cp):
return True, cp
else:
return False, 0
def check_success(gm,player): #gm is game array
for i in range(len(gm)):
if (not any(gm[i]-player)) or (not any(gm[:,i]-player)):
return True
if (not any(np.diag(gm)-player)) or (not any(np.diag(np.fliplr(gm))-player)):
return True
return False
def f_pp0(board, dummy=None):
for b in (board, board.T, np.einsum('ii->i', board)[:, None],
np.einsum('ii->i', board[::-1])[:, None]):
L = np.diff(b, axis=0).any(axis=0) | (b[0] == 0)
ind = L.argmin()
if not L[ind]:
return True, b[0, ind]
return False, 0
def f_pp1(board, dummy=None):
D = np.einsum('ii->i', board)
DP = D != 0
if DP[0] and (D[0] == D).all():
return True, D[0]
L = DP & (D == board).all(0)
I = L.argmax()
if L[I]:
return True, D[I]
L = DP & (D == board.T).all(0)
I = L.argmax()
if L[I]:
return True, D[I]
D = np.einsum('ii->i', board[::-1])
if D[0] and (D[0] == D).all():
return True, D[0]
return False, 0
def stress_test(n, k, p, wr=0.1, fr=0.4):
from timeit import timeit
data = np.random.randint(1, p+1, (k, n, n))
data *= np.random.random((k, n, n)) < fr
w = np.where(np.random.random((k,)) < wr)[0][:, None]
pw = np.random.randint(1, p+1, w.shape)
wp = np.random.randint(-2, 2*n, w.shape)
i = np.where(wp < n, np.arange(n), wp-n)
j = np.where((wp >= n) | (wp < 0), np.arange(n), wp)
j[wp.ravel()==-1, :] == np.arange(n)[::-1]
data[w, i, j] = pw
glb = dict(data=data, p=p)
kwds = dict(number=10, globals=glb)
ref = None
for f, glb['f'] in globals().items():
if f.startswith('f_'):
print('{:<4s}: {:8.6f} ms'.format(f[2:], timeit("for d in data: f(d, p)", **kwds) * 1000 / k))
if ref is None:
ref = np.array([glb['f'](d, p) for d in data])
print(np.count_nonzero(ref))
else:
assert (ref == np.array([glb['f'](d, p) for d in data])).all()
以上是关于numpy逻辑运算问题的主要内容,如果未能解决你的问题,请参考以下文章