Python :沿轴矢量化条件和
Python : Vectorized conditional sum along a axis
有没有办法在某些条件下沿轴求和?
所以我有一个这样的数组,可以沿 0 轴求和。
#array creation:
tpfnfpArray = np.zeros((1000,3))
for i in range(1000):
tpfnfpArray[i,:] = (i,i,i)
#first result
tp,fn, fp = np.sum(tpfnfpArray,axis=0)
#preparing second result
tp2,fp2,fn2,tn2 = (0,0,0,0)
到目前为止一切顺利。现在我想在这样的条件下得到另一个结果 (tp2,fp2,fn2,tn2):
for i in range(1000):
if tpfnfpArray[i][0] > 0 or tpfnfpArray[i][1]>0:
if tpfnfpArray[i][2] > 0: # 0,1,1 or 1,0,1
tp2+=1
else: # 0,1,0 or 1,0,0
fp2+=1
else:
if tpfnfpArray[i][2] > 0: # 0,0,1
fn2+=1
else: # 0,0,0
tn2+=1
是否可以在不遍历第一个数组的每一行的情况下完成这样的事情?
您可以使用矢量化布尔运算进行计算:
import numpy as np
# Random binary array
np.random.seed(0)
tpfnfpArray = np.random.randint(0, 2, (1000, 3))
# Loop computation for comparison
tp2, fp2, fn2, tn2 = (0, 0, 0, 0)
for i in range(1000):
if tpfnfpArray[i][0] > 0 or tpfnfpArray[i][1]>0:
if tpfnfpArray[i][2] > 0:
tp2 += 1
else:
fp2 += 1
else:
if tpfnfpArray[i][2] > 0:
fn2 += 1
else:
tn2 += 1
print(tp2, fp2, fn2, tn2)
# 401 377 115 107
# Vectorized computation
tp_m = tpfnfpArray[:, 0] > 0
fn_m = tpfnfpArray[:, 1] > 0
fp_m = tpfnfpArray[:, 2] > 0
tpfn_m = tp_m | fn_m
tp3 = np.count_nonzero(tpfn_m & fp_m)
fp3 = np.count_nonzero(tpfn_m & ~fp_m)
fn3 = np.count_nonzero(~tpfn_m & fp_m)
tn3 = np.count_nonzero(~tpfn_m & ~fp_m)
print(tp3, fp3, fn3, tn3)
# 401 377 115 107
您可以使用如下所示的向量化逻辑运算来实现
import numpy as np
#array creation:
tpfnfpArray = np.zeros((1000,3))
for i in range(1000):
tpfnfpArray[i,:] = (i,i,i)
#first result
tp,fp,fn = np.sum(tpfnfpArray,axis=0)
#preparing second result
tp2,fp2,fn2,tn2 = (0,0,0,0)
gt_zero = tpfnfpArray>0
# if tpfnfpArray[i][0] > 0 or tpfnfpArray[i][1]>0:
cond1 = gt_zero[0] | gt_zero[1]
# --if tpfnfpArray[i][2] > 0:
tp2 = np.sum(cond1 & gt_zero[2])
# --else:
fp2 = np.sum(cond1 & ~gt_zero[2])
# else
# -- if tpfnfpArray[i][2] > 0:
fn2 = np.sum(~cond1 & gt_zero[2])
# -- else:
tn2 = np.sum(~cond1 & ~gt_zero[2])
tp2, fp2, fn2, tn2
有没有办法在某些条件下沿轴求和? 所以我有一个这样的数组,可以沿 0 轴求和。
#array creation:
tpfnfpArray = np.zeros((1000,3))
for i in range(1000):
tpfnfpArray[i,:] = (i,i,i)
#first result
tp,fn, fp = np.sum(tpfnfpArray,axis=0)
#preparing second result
tp2,fp2,fn2,tn2 = (0,0,0,0)
到目前为止一切顺利。现在我想在这样的条件下得到另一个结果 (tp2,fp2,fn2,tn2):
for i in range(1000):
if tpfnfpArray[i][0] > 0 or tpfnfpArray[i][1]>0:
if tpfnfpArray[i][2] > 0: # 0,1,1 or 1,0,1
tp2+=1
else: # 0,1,0 or 1,0,0
fp2+=1
else:
if tpfnfpArray[i][2] > 0: # 0,0,1
fn2+=1
else: # 0,0,0
tn2+=1
是否可以在不遍历第一个数组的每一行的情况下完成这样的事情?
您可以使用矢量化布尔运算进行计算:
import numpy as np
# Random binary array
np.random.seed(0)
tpfnfpArray = np.random.randint(0, 2, (1000, 3))
# Loop computation for comparison
tp2, fp2, fn2, tn2 = (0, 0, 0, 0)
for i in range(1000):
if tpfnfpArray[i][0] > 0 or tpfnfpArray[i][1]>0:
if tpfnfpArray[i][2] > 0:
tp2 += 1
else:
fp2 += 1
else:
if tpfnfpArray[i][2] > 0:
fn2 += 1
else:
tn2 += 1
print(tp2, fp2, fn2, tn2)
# 401 377 115 107
# Vectorized computation
tp_m = tpfnfpArray[:, 0] > 0
fn_m = tpfnfpArray[:, 1] > 0
fp_m = tpfnfpArray[:, 2] > 0
tpfn_m = tp_m | fn_m
tp3 = np.count_nonzero(tpfn_m & fp_m)
fp3 = np.count_nonzero(tpfn_m & ~fp_m)
fn3 = np.count_nonzero(~tpfn_m & fp_m)
tn3 = np.count_nonzero(~tpfn_m & ~fp_m)
print(tp3, fp3, fn3, tn3)
# 401 377 115 107
您可以使用如下所示的向量化逻辑运算来实现
import numpy as np
#array creation:
tpfnfpArray = np.zeros((1000,3))
for i in range(1000):
tpfnfpArray[i,:] = (i,i,i)
#first result
tp,fp,fn = np.sum(tpfnfpArray,axis=0)
#preparing second result
tp2,fp2,fn2,tn2 = (0,0,0,0)
gt_zero = tpfnfpArray>0
# if tpfnfpArray[i][0] > 0 or tpfnfpArray[i][1]>0:
cond1 = gt_zero[0] | gt_zero[1]
# --if tpfnfpArray[i][2] > 0:
tp2 = np.sum(cond1 & gt_zero[2])
# --else:
fp2 = np.sum(cond1 & ~gt_zero[2])
# else
# -- if tpfnfpArray[i][2] > 0:
fn2 = np.sum(~cond1 & gt_zero[2])
# -- else:
tn2 = np.sum(~cond1 & ~gt_zero[2])
tp2, fp2, fn2, tn2