【问题标题】:Python : Vectorized conditional sum along a axisPython:沿轴的向量化条件和
【发布时间】:2019-11-20 13:37:16
【问题描述】:

有没有办法在某些条件下沿轴求和? 所以我有一个这样的数组,可以沿 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

是否可以不循环遍历第一个数组的每一行?

【问题讨论】:

  • 无关,但我想tp,fp,fn的顺序实际上应该是tp,fn,fp,从数组名称tpfnfpArray来看?
  • 你完全正确,是个错误!
  • 在 pandas 中,您可以像我的示例 colab.research.google.com/drive/… 那样以矢量化方式对行应用 lambda 函数。当然可以在 numpy 中完成(pandas 是基于 numpy 构建的)

标签: python numpy vectorization


【解决方案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

【讨论】:

    【解决方案2】:

    您可以使用如下的矢量化逻辑运算来完成此操作

    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
    

    【讨论】:

      猜你喜欢
      • 2021-12-12
      • 1970-01-01
      • 2018-05-23
      • 2020-06-30
      • 1970-01-01
      • 2017-12-01
      • 2020-03-09
      • 2016-05-15
      • 1970-01-01
      相关资源
      最近更新 更多