ndarray的运算

逻辑运算

数据集:

>>> test_score
array([[59, 90, 69, 65, 82],
       [82, 47, 58, 76, 73],
       [90, 79, 50, 56, 80],
       [60, 48, 53, 49, 97]])

作为一个ndarray数组,我们也可以直接对它进行一些逻辑运算,比如( > , < , =)等,ndarray数组将会对数组内所有元素进行逻辑运算并返回一个新的ndarray数组作为结果集

# 生成 40 <= x <= 100 的10行5列的二维数组
score = np.random.randint(40,100,(10,5))
# 取后4行数据
test_score = score[6:,:]
test_score > 60 

>>>
array([[False,  True,  True,  True,  True],
       [False,  True,  True,  True,  True],
       [ True,  True, False,  True,  True],
       [ True,  True, False,  True,  True]])
test_score[test_score > 60] = 1
test_score

>>>
array([[47,  1,  1,  1, 44],
       [ 1,  1,  1,  1,  1],
       [ 1, 42,  1,  1,  1],
       [ 1,  1, 59, 40,  1]])

通用判断函数

数据集:

>>> score[0:2,:]
array([[94, 56, 91, 89, 47],
       [81, 87, 57, 68, 52]])
  • np.all()
    判断参数是否全部符合条件
# 判断前两名同学的成绩 [0:2,:] 是否全部及格
np.all(score[0:2,:] > 60)

>>>
False
  • np.any()
    判断参数是否存在符合条件的元素
# 判断前两名同学的成绩 [0:2,:] 是否有大于80分的
np.any(score[0:2,:] > 80 )

>>>
True

np.where(三元运算符)

temp数据集:

>>> temp
array([[94, 56, 91, 89],
       [81, 87, 57, 68],
       [86, 82, 88, 67],
       [41, 53, 53, 43]])

通过使用np.where能够进行更加复杂的运算,和c,java里的三元运算符很像。

  • np.where()
temp = score[:4,:4]
#判断前4名学生的前4科的成绩,大于60的成绩置1,反之置0
np.where(temp > 60,1,0)

>>>
array([[1, 0, 1, 1],
       [1, 1, 0, 1],
       [1, 1, 1, 1],
       [0, 0, 0, 0]])

复合逻辑需要结合

  • np.logical_and(lg1,lg2...)
    括号里添加2个以上的逻辑运算结合为逻辑与
# 大于60,小于80的置1,反之0
np.where(np.logical_and(temp > 60,temp < 80),1,0)

>>>
array([[0, 0, 0, 0],
       [0, 0, 0, 1],
       [0, 0, 0, 1],
       [0, 0, 0, 0]])
  • np.logical_or(lg1,lg2...)
    括号里添加2个以上的逻辑运算结合为逻辑或
np.where(np.logical_or(temp < 60,temp > 80),1,0)

>>>
array([[1, 1, 1, 1],
       [1, 1, 1, 0],
       [1, 1, 1, 0],
       [1, 1, 1, 1]])

统计指标

a是ndarray数组对象,axis是根据 行(1)或列(0)去统计指标,axis参数可选如果为空,则返回整个数组中的统计指标。

值得一提的是,进行统计的时候,axis轴的取值也就是1,0对应行还是列并不一定,Numpy中不同的API轴的值都不一样,在这里axis,行=1,列=0 。

np.

  • min(a,axis)最小值
  • max(a,axis)最大值
  • median(a,axis)中值
  • mean(a,axis,dtype)平均值
  • std(a,axis,dtype)标准差
  • var(a,axis,dtype)方差
  • argmin(a,axis)返回最小值的索引
  • argmax(a,axis)返回最大值的索引

数据集:

>>> temp
array([[94, 56, 91, 89],
       [81, 87, 57, 68],
       [86, 82, 88, 67],
       [41, 53, 53, 43]])
print("===================\n
不论科目最高分:{}\n
各科成绩的最大分:{}\n
每个同学的最大分:{}".format(np.max(temp),np.max(temp,axis=0),np.max(temp,axis=1)))
print("===================\n
不论科目最低分:{}
\n各科成绩的最低分:{}
\n每个同学的最小份:{}".format(np.min(temp),np.min(temp,axis=0),np.min(temp,axis=1)))
print("===================\n
不论科目整体标准差:{}\n
各科成绩波动情况:{}\n
每个同学的成绩波动:{}".format(np.std(temp),np.std(temp,axis=0),np.std(temp,axis=1)))
print("===================\n
不论科目整体平均分:{}\n
各科成绩的平均分:{}\n
每个同学的平均分{}".format(np.mean(temp),np.mean(temp,axis=0),np.mean(temp,axis=1)))

输出

===================
不论科目最高分:94
各科成绩的最大分:[94 87 91 89]
每个同学的最大分:[94 87 88 53]
===================
不论科目最低分:41
各科成绩的最低分:[41 53 53 43]
每个同学的最小份:[56 57 67 41]
===================
不论科目整体标准差:17.716517716526575
各科成绩波动情况:[20.45116134 15.14100393 17.34034313 16.28457859]
每个同学的成绩波动:[15.4029218  11.62701595  8.22724134  5.54526825]
===================
不论科目整体平均分:71.0
各科成绩的平均分:[75.5  69.5  72.25 66.75]
每个同学的平均分:[82.5  73.25 80.75 47.5 ]

如果需要统计出某科最高分对应的是哪个同学?

数据集:

>>> temp
array([[94, 56, 91, 89],
       [81, 87, 57, 68],
       [86, 82, 88, 67],
       [41, 53, 53, 43]])
  • np.argmax(temp,axis=)
  • np.argmin(temp,axis=)
print("每个同学最高分的所属科目:{}".format(np.argmax(temp,axis=1 )))
print("每个科目最高分的是哪个同学:{}".format(np.argmax(temp,axis=0 )))

输出

每个同学最高分的所属科目:[0 1 2 1]
每个科目最高分的是哪个同学:[0 1 0 0]

数组间的运算

广播机制

数组在进行矢量化运算时,要求数组的形状是相等的。

当形状不相等的数组执行算术运算的时候,就会出现广播机制,该机制会对数组进行扩展,使数组的shape属性值一样,这样,就可以进行矢量化运算了。下面举个例子:

arr1 = np.array([[0],[1],[2],[3]])
print(arr1.shape)
arr2 = np.array([1,2,3])
print(arr2.shape)
arr1 + arr2

>>>
(4, 1)
(3,)
array([[1, 2, 3],
       [2, 3, 4],
       [3, 4, 5],
       [4, 5, 6]])

可以看到arr1和arr2的shape属性并不一样,但最后两者成功的进行了矢量相加,要归功于ndarray的广播机制。

关于广播机制,在上述代码中 arr1 是4行1列,arr2 是1行3列。这两个数组要进行相加,按照广播机制会对数组arr1和arr2都进行扩展,使得数组arr1和arr2都变成4行3列。

广播机制实现了时两个或两个以上数组的运算,即使这些数组的shape不是完全相同的,只需要满足如下任意一个条件即可。

  1. 数组的某一维度等长
  2. 其中一个数组的某一维为1

广播机制需要扩展维度小的数组,使得它与维度最大的数组的shape值相同,以便使用元素级函数或者运算符进行运算

矩阵运算

np.dot(arr1,arr2)

矩阵和数组(ndarray)都些许区别,数组可以试多维的但矩阵必须是二维的。

score2 = score[:,:2]
theta = np.array([[0.7],[0.3]])
result = np.dot(score2,theta)
result

>>>
array([[79.5],
       [60.8],
       [61.3],
       [90.4],
       [68.5],
       [76.3],
       [68.3],
       [71.5],
       [86.7],
       [56.4]])

所念皆星河