赞
踩
Q: 创建一个2行2列矩阵并且元素为布尔类型的True
A:
np.full((2,2), True, dtype=bool)
原因:
不知道: np.full() 函数
(竞赛论坛解释)
使用方法:
np.full((shape), full_value = 待写的值, dtype = 待写值的数据类型 )
np.arange() 和 np.linspace() 的用法及区别
(详细介绍网址)
介绍:
"""总结:
arange 侧重点在于增量,不管产生多少个数
linspace 侧重于num, 即要产生多少个元素,不在乎增量
"""
代码:
import numpy as np
np_ar = np.arange(start=5, stop=50, step=5)
np_lin = np.linspace(start=5, stop=50, num=10, dtype=int)
print(np_ar)
print("*"*15)
print(np_lin)
运行结果:
[ 5 10 15 20 25 30 35 40 45]
***************
[ 5 10 15 20 25 30 35 40 45 50]
Q : 矩阵元素均为0—10之间的随机数
A :
import numpy as np
a = np.random.rand(9)*10
a.reshape(3, 3)
结果:
array([[2.07155462, 6.51925523, 8.61820964],
[7.87458464, 2.03604928, 2.93732002],
[3.07287555, 9.86494152, 8.90354491]])
其中这里要注意,np.random.函数方法() 的使用
(点击查看)
查看np变量的数据类型
Q : 查看result的数据类型
A :
import numpy as np
list_name = range(1, 10, 1)
np_list = np.array(list_name)
result = np_list.reshape(3, 3)
print(result.dtype)
print(type(result))
int32
<class 'numpy.ndarray'>
出现不一致的原因:
type(变量) 表示的是整个变量的类型
np变量名.dtype 表示的是变量中存储的数据的类型
dtype = data type --> 所以才是 变量中的数据的类型。
本题要考察的是 查看 result 的数据类型,即为 result 的数据类型。
Q : 查看result的内存占用
A :
#方法一:直接查看
print(result.nbytes)
#方法2手动计算
print(result.itemsize * 9)
72
72
(参考文章)中给出的是另一种查看方式
import sys
import numpy as np
List = [1,2,3,4,5,6,7,8,9]
result = np.array(List)
sys.getsizeof(result)
132
疑问:
针对同一个数据而言,不同的查看方式占用的内存是不一样的呢?
那么针对这种现象,先看一下一个数字占用的内存大小。
import sys
import numpy as np
List = [1]
result = np.array(List)
print(sys.getsizeof(result)) # 通过sys进行查看
print(result.nbytes) # 通过ndarray的属性进行查看
100
4
从上面看出来,result内存占用的初值是不一样的。猜测:这两种不同的统计方式有各自的初值使用。
import sys
import numpy as np
List = []
result = np.array(List)
print(sys.getsizeof(result)) # 通过sys进行查看
print(result.nbytes) # 通过ndarray的属性进行查看
96
0
sys.getsizeof()方法用于获取变量中存储数据的大小
np变量.nbytes 表示这个变量占用内存的大小
提取元素的不同方式
方式1. 先提取行(列)在提取列(行)
import numpy as np
list_name = range(1, 10, 1)
np_list = np.array(list_name)
result = np_list.reshape(3, 3)
result[2][0]
7
方式2. 行列以 [ ] 的形式一同给出 [行数 , 列数]
import numpy as np
list_name = range(1, 10, 1)
np_list = np.array(list_name)
result = np_list.reshape(3, 3)
result[2, 0]
7
Q : 提取result中的所有偶数
A :
import numpy as np
list_name = range(1, 10, 1)
np_list = np.array(list_name)
result = np_list.reshape(3, 3)
for i in range(0, 3):
for j in range(0, 3):
num = result[i, j]
if num % 2 == 0:
print(num)
2
4
6
8
print(result[result % 2 == 0])
[2 4 6 8]
通过上述例子可以看出, 方法2 远远简单于方法1。
那么 方法2 的主要思想是什么呢?
首先介绍一下 numpy :
NumPy(Numerical Python)是Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵。
方法1 是 Python自身的嵌套列表(nested list structure)结构, 使用循环去遍历,然后提取数值进行相应操作,一旦数据量庞大,那么就难以高效的计算
为了改变这种缺陷,那么引入了 numpy 。
方法2 是 使用 numpy 数组计算的特点。
将数组中的每个元素分别进行逐一判定,类似于 (并行计算,个人观点),然后将结果以 组数据的形式输出。
组数据 = np.array格式的数据 (个人观点)
Q :将result中所有奇数修改为666
A :
result[result % 2 != 0] = 666
# 另一种写法:
# result[result % 2 == 1] = 666
result
array([[666, 2, 666],
[ 4, 666, 6],
[666, 8, 666]])
总共分 3 步:
1. 条件
2. 筛选数值
3. 在原变量上替换
参考文章:(numpy数组中值的替换)
Q : 交换第一列与第二列
A :
采用中间变量交换顺序法:
a = 3
b = 1
# 引入中间量 c
c = a
a = b
b = c
print("a = ", a)
print("b = ", b)
# 结果:
# a = 1
# b = 3
# 说明已经完成了顺序交换
通过这种思想进行交换:
import numpy as np
list_name = range(1, 10)
np_arr = np.array(list_name).reshape(3, 3)
# print(np_arr)
temp = np_arr[:, 0]
np_arr[:, 0] = np_arr[:, 1]
np_arr[:, 1] = temp
print(np_arr)
[[2 2 3]
[5 5 6]
[8 8 9]]
发现出现错误:
原因:
numpy 的计算是将 python中的循环整合的结果。那么我们在执行
temp = np_arr[:, 0]
将第一列数据中的值给了中间变量temp。
np_arr[:, 0] = np_arr[:, 1]
将第二列数据中的值给了np_arr[:, 0]中,此时 temp跟随了np_arr[:, 0]的变化
说名 temp = np_arr[:, 0]的一个“小名”, 并非np_arr[:, 0]的复制项。
np_arr[:, 1] = temp
已经变化的temp中的值再给np_arr[:, 1]
这里说明 : numpy变量取值后的数据会跟随 变量的改变而改变
举例:
import numpy as np
list_name = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
np_arr = np.array(list_name).reshape(3, 3)
# print(np_arr)
temp = np_arr[:, 0]
print(temp)
np_arr[:, 0] = np_arr[:, 0] + 100
print(temp)
[1 4 7]
[101 104 107]
因此 在numpy中直接采用中间变量赋值的方法进行数据的交换是不正确的!!!
(Numpy 如何交换两行和两列)
正确解决方法:
import numpy as np
list_name = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
np_arr = np.array(list_name).reshape(3, 3)
# print(np_arr)
temp = np.copy(np_arr[:, 0])
np_arr[:, 0] = np_arr[:, 1]
np_arr[:, 1] = temp
print(np_arr)
[[2 1 3]
[5 4 6]
[8 7 9]]
另一种方法是:
直接交换numpy行或列的下标
a = np_arr[:, [1, 0, 2]]
print(a)
[[1 2 3]
[4 5 6]
[7 8 9]]
Q : 判断两个矩阵中是不是所有元素都相等 = 判断两个矩阵是否有任何元素不同
A :
使用 .all() 函数进行判定。
import numpy as np
a = np.array([1, 2, 3])
b = np.array([2, 4, 3])
print((a == b))
print((a == b).all())
print((a == b).any())
[False False True]
False
True
all() 当所有的项全为True时才是 True , 类似于 开关的串联电路
any() 只要有一个为True则为True, 类似与 开关的并联电路
注意:
这里的( a == b)的判定是每一项,项与项之间对应的判定。
Q : 统计变量中元素出现的次数
A :
import numpy as np
import pandas as pd
random_data = np.random.randint(1, 7, 10000)
# random_data.mean() # 均值
# random_data.std() # 标准差
random_data = pd.DataFrame(random_data)
random_data.value_counts()
6 1737
5 1724
3 1656
2 1653
1 1621
4 1609
dtype: int64
unique,count=np.unique(random_data,return_counts=True)
data_count=dict(zip(unique,count))
{1: 1702, 2: 1646, 3: 1658, 4: 1703, 5: 1645, 6: 1646}
# 3.1 一维数据
import collections
data_count2=collections.Counter(random_data)
print(data_count2)
Counter({4: 1732, 6: 1697, 1: 1683, 3: 1643, 5: 1629, 2: 1616})
# 3.2
import collections
random_data2 = random_data.reshape(2, 5000)
data_count2=collections.Counter(random_data2.flatten())
print(data_count2)
Counter({1: 1718, 3: 1697, 4: 1676, 6: 1656, 2: 1630, 5: 1623})
注意: 如果不使用 flatten() 则会报错:
TypeError: unhashable type: 'numpy.ndarray'
Q:计算两个矩阵不同元素的个数(说明:这里指的是相同位置,但元素值是不一样的。)
A :
import numpy as np
a = np.arange(1, 10).reshape(3, 3)
b = np.array([[1, 2, 3],
[11, 22, 33],
[111, 222, 333]])
print(a)
print(b)
element_uneval = np.argwhere(a != b)
print(len(element_uneval))
[[1 2 3]
[4 5 6]
[7 8 9]]
[[ 1 2 3]
[ 11 22 33]
[111 222 333]]
6
print(element_uneval)
运行结果:
[[1 0]
[1 1]
[1 2]
[2 0]
[2 1]
[2 2]]
下面就来解释一下,np.argwhere() 函数。
首先我们来看一下 np.where() 函数。、
参考文章: (np.where()用法总结)
where = 在哪里 = 表示地点 = 寻找下标(numpy中的含义)
使用方法:
np.where(condition, 满足条件填充值,不满足条件填充值)
返回值是 一个数组,可以进行广播。
代码实例:
con = np.where(a>3) # 这里的a 承接的是本题中的a
con1 = np.where(a>3, "大于3", "不大于3")
print(con)
print()
print(con1)
(array([1, 1, 1, 2, 2, 2], dtype=int64), array([0, 1, 2, 0, 1, 2], dtype=int64))
[['不大于3' '不大于3' '不大于3']
['大于3' '大于3' '大于3']
['大于3' '大于3' '大于3']]
要指明一下:
第一个结果:
print(con) 输出的是一个元组类型的数据,数据中的元素分成两部分:第一部分是满足条件的下标的行值,第二部分是满足条件的下标的列值。
np.where(a>3)代表的是:没有写填充值的话,便只输出,数组中满足条件的(行下标组成的np.array数组, 列下标组成的np.array数组)
print(con1) 的输出是在满足条件的位置填上“要填充的值”, 不满足的条件的填上“不满足要填充的值”
(array([1, 1, 1, 2, 2, 2], dtype=int64), array([0, 1, 2, 0, 1, 2], dtype=int64))
这种形式的输出不好看,使用起来不方便
那么怎么进行改进,此时便引入了np.argwhere()
使用方法:
np.argwhere(condition)
输出是: [ 满足条件的行下标 , 满足条件的列下标 ]
con_arg = np.argwhere(a>3)
print(con_arg)
[[1 0]
[1 1]
[1 2]
[2 0]
[2 1]
[2 2]]
要想统计两矩阵的不同元素个数, 便使用 len() 函数 计算 np.argwhere() 的输出值。
使用的是 :
np.linalg.det( 矩阵名称 )
总结:
np.linalg是numpy中,用来计算线性代数中的相关知识。其中 linalg = linear algebra
这里给出常用的函数方法:
求方阵的逆 = np.linalg.inv(矩阵)
求矩阵(不需要是方阵)的逆 = np.linalg.pinv(矩阵)
求行列式 = np.linalg.det(矩阵)
求 Ax = b 的解 = np.linalg.solve(A, b)
求 Ax = ax 的特征值 = np.linalg.eigvals(A)
一起求解特征值和特征向量 :
特征值名, 特征向量名 = np.linalg.eig(A)
进行SVD(Singular Value Decomposition,奇异值分解):
U,Sigma,V = np.linalg.svd(分解矩阵,full_matrices=False)
该函数返回3个矩阵——U、Sigma和V,其中U和V是正交矩阵,Sigma包含输入矩阵的奇异值。
参考文章 (numpy.linalg模块)
Q : 两个np.matrix格式矩阵的对应元素乘积.
A :
使用 np.multiply() 方法进行对应元素相乘
res_r_mat = np.mat(res_r)
res_c_mat = np.matrix(res_c)
# 这里是承接了前面的运行结果
res_multi = np.multiply(res_r_mat, res_c_mat)
print(res_multi)
[[ 8 5 18]
[ 5 8 18]
[56 56 81]]
注意对比:
这里的
np.matrix() 格式的矩阵 对应元素相乘的方法是: np.multiply(变量1, 变量2)
在功能上等于
np.array() 格式的数组,对应元素相乘方法为:array变量名 * array变量名 = np.multiply(变量1, 变量2)
参考文章(numpy实现矩阵的拼接)
# 按行拼接
res_con_r = np.r_[res_r, res_c] # !!! 这是使用的是 中括号
print(res_con_r)
# 按列拼接
res_con_c = np.c_[res_r, res_c] # !!! 这是使用的是 中括号
print(res_con_c)
[[2 1 3]
[5 4 6]
[8 7 9]
[4 5 6]
[1 2 3]
[7 8 9]]
[[2 1 3 4 5 6]
[5 4 6 1 2 3]
[8 7 9 7 8 9]]
这种拼接方式,能不能广播呢??
# 检查是否可以广播
a = np.array([1, 2, 3, 4, 5, 6]).reshape(2, 3)
b = np.array([9, 8, 7, 6, 5, 4]).reshape(3, 2)
c = np.r_[a, b]
ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 3 and the array at index 1 has size 2
程序报错,行列维度有问题,说明不能够广播。
stack = 堆叠,堆栈
h = horizontal = 水平的,水平线
按照行进行拼接:
np.hstack((矩阵1, 矩阵2))
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6]])
b = np.array([["a", "b", "c"],
["d", "e", "f"]])
np.hstack((a, b))
array([['1', '2', '3', 'a', 'b', 'c'],
['4', '5', '6', 'd', 'e', 'f']], dtype='<U11')
v = vertical = 纵向的,竖的
按照列进行拼接:
np.vstack((矩阵1, 矩阵2))
np.vstack((a, b))
array([['1', '2', '3'],
['4', '5', '6'],
['a', 'b', 'c'],
['d', 'e', 'f']], dtype='<U11')
注意 :
np.vstack(()) 和 np.hstack(()) 使用了两个括号
方法1 和 方法2 是运行方式和结果是不一样的要仔细观察。
pad = 填充,覆盖
padding = 填充
此处的 np.pad() 和 tensorflow中的卷积神经网络中 tf.keras.layers.Conv2D中的参数 padding ,均是表示在数据周围进行什么样的填充方式。
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6]])
np.pad(a, pad_width=1, mode="constant", constant_values=0)
array([[0, 0, 0, 0, 0],
[0, 1, 2, 3, 0],
[0, 4, 5, 6, 0],
[0, 0, 0, 0, 0]])
理解成,进行了多少行的全0填充
pad_width = 数字 , 表示在数据周围进行多少行填充方式
mode = “填充模式”
constant_values = 数字 ,准备用什么值进行填充
np.pad(a, pad_width=2, mode="mean")
array([[3, 3, 2, 4, 4, 3, 3],
[3, 3, 2, 4, 4, 3, 3],
[2, 2, 1, 2, 3, 2, 2],
[5, 5, 4, 5, 6, 5, 5],
[3, 3, 2, 4, 4, 3, 3],
[3, 3, 2, 4, 4, 3, 3]])
解释一下这个结果:
pad_width = 2 进行了 两层填充
mode = “mean” 进行均值填充
这个地方有疑问??
Q : 找到new中大于1的元素的值
A :
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6]])
new = np.pad(a, pad_width=1, mode="constant", constant_values=1)
new[new > 1]
array([2, 3, 4, 5, 6])
Q : 找到这些 大于1 的值 的位置
A : 位置 = where , argwhere
# 找到大于 1 的位置
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6]])
new = np.pad(a, pad_width=1, mode="constant", constant_values=1)
con_index = np.where(new > 1)
con_index1 = np.argwhere(new > 1)
print(con_index)
print(con_index1)
(array([1, 1, 2, 2, 2], dtype=int64), array([2, 3, 1, 2, 3], dtype=int64))
[[1 2]
[1 3]
[2 1]
[2 2]
[2 3]]
Q : 将满足条件的元素值,进行修改
A :
new[new > 1] = 9
new
注意 : 第25题(计算两个矩阵不同元素的个数中也用到了 argewhere方法), 回顾查看
new.sum(axis = 0)
# array([ 4, 12, 20, 20, 4])
np.sum(new, axis=1)
# array([ 5, 21, 29, 5])
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。