数据分析——数据可视化(一)
一、jupter的使用
1. 快捷键的使用
(1) esc 从输入模式退出到命令模式
(2) a 在当前cell上创建一个新的cell
(3) b 在当前cell下面创建一个新的cell
(4) dd 删除当前cell
(5) m 切换到markdown模式
(6) ctrl+回车 运行cell
(7) shift+回车 运行当前cell并创建一个新的cell
2. jupter 的两种打开方式
(1)直接通过 anaconda 下载打开
(2)通过 pycharm 打开,前提得是专业版
二、Numpy 数组
1. Numpy 数组的核心特性
(1)多维性:支持 0 维(标量)、1 维(向量)、2维(矩阵)及更高维数组。
(2)同质性:所有元素类型必须一致。
(3)高效性:基于连续内存块存储,支持向量化运算。
多维性
NumPy数组支持任意维度的数据结构,从一维向量到高维张量均可表示。
-
一维数组(向量):
import numpy as np arr_1d = np.array([1, 2, 3]) # 形状为 (3,) -
二维数组(矩阵):
arr_2d = np.array([[1, 2], [3, 4]]) # 形状为 (2, 2) -
三维数组(张量):
arr_3d = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) # 形状为 (2, 2, 2)
同质性
数组中的所有元素必须是相同数据类型,确保高效的内存布局和计算。
-
整数类型数组:
int_arr = np.array([1, 2, 3], dtype=np.int32) -
浮点类型数组:
float_arr = np.array([1.0, 2.5, 3.7], dtype=np.float64) -
类型强制转换:若混合类型,NumPy会自动向上转型。
mixed_arr = np.array([1, 2.5, '3']) # 转为字符串类型
高效性
NumPy底层用C实现,支持向量化操作和广播机制,避免显式循环。
-
向量化运算:
a = np.array([1, 2, 3]) b = np.array([4, 5, 6]) result = a + b # 逐元素相加,结果为 [5, 7, 9] -
广播机制:
a = np.array([[1], [2], [3]]) # 形状 (3, 1) b = np.array([10, 20]) # 形状 (2,) result = a * b # 广播后形状为 (3, 2),结果为 [[10, 20], [20, 40], [30, 60]] -
高效函数库:
arr = np.random.rand(1000000) # 生成百万随机数 mean = np.mean(arr) # 快速计算均值2. ndarray的属性
shape
shape返回一个元组,表示数组的维度大小。例如,二维数组(3, 2)表示3行2列。import numpy as np arr = np.array([[1, 2], [3, 4], [5, 6]]) print(arr.shape) # 输出 (3, 2)ndim
ndim返回数组的维度数量(轴数)。标量为0,向量为1,矩阵为2。arr = np.array([1, 2, 3]) print(arr.ndim) # 输出 1size
size返回数组元素的总数。arr = np.array([[1, 2], [3, 4]]) print(arr.size) # 输出 4dtype
dtype返回数组元素的数据类型。arr = np.array([1, 2], dtype=np.float32) print(arr.dtype) # 输出 float32T
T返回数组的转置(行列互换)。arr = np.array([[1, 2], [3, 4]]) print(arr.T) # 输出 [[1 3], [2 4]]itemsize
itemsize返回单个数组元素的字节大小。arr = np.array([1, 2], dtype=np.int16) print(arr.itemsize) # 输出 2(int16占2字节)nbytes
nbytes返回数组所有元素占用的总字节数(size * itemsize)。arr = np.array([[1, 2], [3, 4]], dtype=np.int32) print(arr.nbytes) # 输出 16(4元素 × 4字节)flags
flags返回数组的内存布局信息(如是否连续存储、是否可写等)。arr = np.array([1, 2]) print(arr.flags) # 输出示例: # C_CONTIGUOUS : True # F_CONTIGUOUS : True # OWNDATA : True # WRITEABLE : True3. ndarray 的创建
(1)从Python列表或元组创建
通过np.array()函数将Python列表或元组转换为ndarray。指定dtype参数可明确数据类型,未指定时NumPy自动推断。
import numpy as np
arr1 = np.array([1, 2, 3]) # 一维数组
arr2 = np.array([[1, 2], [3, 4]]) # 二维数组
(2)使用内置函数生成特殊数组
np.zeros(shape):生成全0数组,shape为元组形式(如(3,2))。np.ones(shape):生成全1数组。np.full(shape, fill_value):填充指定值。np.eye(N):生成N×N单位矩阵。
zeros_arr = np.zeros((2, 3)) # 2行3列全0数组
ones_arr = np.ones((3,)) # 一维全1数组
full_arr = np.full((2, 2), 5) # 2×2数组填充为5
(3)生成数值序列
np.arange(start, stop, step):类似Python的range,生成等差序列。np.linspace(start, stop, num):生成等间隔的num个数值。
seq1 = np.arange(0, 10, 2) # [0, 2, 4, 6, 8]
seq2 = np.linspace(0, 1, 5) # [0., 0.25, 0.5, 0.75, 1.]
(4)随机数组生成
np.random.rand(d0, d1, ...):生成[0,1)均匀分布的随机数。np.random.randn(d0, d1, ...):生成标准正态分布随机数。np.random.randint(low, high, size):生成指定范围内的随机整数。
rand_arr = np.random.rand(2, 3) # 2×3均匀分布数组
randn_arr = np.random.randn(3) # 一维正态分布数组
int_arr = np.random.randint(1, 10, (2,2)) # 1~10的2×2随机整数
4. ndarray的数据类型
NumPy的ndarray(多维数组)支持多种数据类型(dtype),这些类型决定了数组中元素的存储方式和计算行为。以下是常见的数据类型分类及说明:
数值类型
-
整数类型:
int8,int16,int32,int64:有符号整数,分别占8/16/32/64位。uint8,uint16,uint32,uint64:无符号整数,范围从0开始。- 示例:
np.array([1, 2], dtype=np.int32)
-
浮点类型:
float16:半精度浮点数(16位)。float32:单精度浮点数(32位)。float64:双精度浮点数(64位,默认类型)。- 示例:
np.array([1.0, 2.0], dtype=np.float32)
-
复数类型:
complex64:实部和虚部均为float32。complex128:实部和虚部均为float64(默认)。- 示例:
np.array([1+2j], dtype=np.complex64)
其他类型
-
布尔类型:
bool_:占1字节,值为True或False。- 示例:
np.array([True, False], dtype=np.bool_)
-
字符串类型:
str_或U<n>:Unicode字符串,<n>表示最大长度(如U10)。- 示例:
np.array(['hello'], dtype='U10')
-
字节类型:
bytes_或S<n>:ASCII字符串,<n>为最大长度。- 示例:
np.array([b'data'], dtype='S4')
类型转换
- 使用
astype()方法显式转换数据类型:arr = np.array([1, 2, 3]) arr_float = arr.astype(np.float64) # 转换为浮点型
特殊值支持
- 浮点类型支持
np.nan(非数字)和np.inf(无穷大):arr = np.array([1.0, np.nan, np.inf], dtype=np.float32)
类型检查
- 通过
dtype属性查看数组类型:print(arr.dtype) # 输出如:float32
默认类型推断规则
- 无小数点数据默认为
int64(64位系统)或int32(32位系统)。 - 含小数点数据默认为
float64。 - 混合类型(如整数与浮点数)会向上转型为浮点型。
5. ndarray索引与切片
NumPy的ndarray支持多种索引和切片方式,类似于Python列表但功能更强大。基本索引通过方括号[]实现,索引从0开始。
一维数组示例:
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(arr[0]) # 输出1
print(arr[1:4]) # 输出[2 3 4]
多维数组示例:
# 逗号左边代表行,逗号右边代表列
arr_2d = np.array([[1, 2, 3], [4, 5, 6]])
print(arr_2d[0, 1]) # 输出2(第0行第1列)
print(arr_2d[:, 1]) # 输出[2 5](所有行的第1列)
print(arr[1:3, 3:5]) # 取属于 1-3(左闭右开) 行,并且属于 3-5(左闭右开) 列之间的元素
高级索引技术
布尔索引: 通过布尔数组筛选数据:找出数组中大于 2 的数据
arr = np.array([1, 2, 3, 4])
mask = arr > 2
print(arr[mask]) # 输出[3 4]
整数数组索引: 使用整数数组作为索引:
arr = np.array([10, 20, 30, 40])
indices = [0, 2]
print(arr[indices]) # 输出[10 30]
多维数组整数索引:
arr = np.array([[1, 2], [3, 4], [5, 6]])
rows = [0, 1, 2]
cols = [0, 1, 0]
print(arr[rows, cols]) # 输出[1 4 5]
arr = np.random.randint(1, 100, (4, 8))
print(arr)
运行结果:arr = [[77 33 13 46 63 80 64 18]
[53 52 16 85 27 84 98 69]
[75 4 4 73 72 83 77 29]
[88 39 48 81 83 99 2 92]]
测试代码:
print(arr[2][arr[2] > 50]) # 取第二行中大于 50 的元素
print(arr[:,3][arr[:,3] > 50]) # 取第二列中大于 50 的元素
切片操作技巧
步长切片:
arr = np.array([0, 1, 2, 3, 4, 5])
print(arr[1:5:2]) # 输出[1 3](从索引1到5,步长2)
多维切片:
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(arr[:2, 1:]) # 输出[[2 3][5 6]](前两行,第1列及之后)
视图与副本
切片操作返回的是视图(共享内存),而高级索引返回副本:
arr = np.array([1, 2, 3, 4])
slice_view = arr[1:3] # 视图
copy_arr = arr[[1, 2]] # 副本
实用示例
条件修改:
arr = np.array([1, 2, 3, 4])
arr[arr > 2] = 0 # 将大于2的元素置0
print(arr) # 输出[1 2 0 0]
结构化索引:
data = np.array([(1, 2.), (3, 4.)], dtype=[('x', 'i4'), ('y', 'f4')])
print(data['x']) # 输出[1 3](通过字段名索引)
6. ndarray的运算
ndarray 的基本运算
NumPy 的 ndarray 支持多种数学运算,包括逐元素运算、矩阵运算和统计运算。逐元素运算会对数组中的每个元素单独进行计算。
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# 逐元素加法
result = a + b # 输出: array([5, 7, 9])
# 逐元素乘法
result = a * b # 输出: array([4, 10, 18])
# 逐元素平方
result = a ** 2 # 输出: array([1, 4, 9])
广播机制
NumPy 的广播机制允许不同形状的数组进行运算。较小的数组会“广播”到较大数组的形状,以便进行逐元素运算。
案例1:
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([1, 2, 3])
# 广播加法
result = a + b # 输出: array([[2, 4, 6], [5, 7, 9]])
案例2:
# 广播机制
# 不同规格矩阵相加减:先扩展再相加减
a = np.array([1, 2, 3])
b = np.array([[4],[5],[6]])
print(a + b)
'''
a扩展后的矩阵:
1 2 3
1 2 3
1 2 3
b扩展后的矩阵:
4 4 4
5 5 5
6 6 6
扩展后得到的矩阵再进行加减
'''
矩阵乘法
使用 np.dot() 或 @ 运算符进行矩阵乘法。矩阵乘法遵循线性代数规则,要求第一个矩阵的列数与第二个矩阵的行数相等。
案例1:
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
# 矩阵乘法
result = np.dot(a, b) # 输出: array([[19, 22], [43, 50]])
result = a @ b # 同上
案例2:
# 矩阵的运算
a = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
b = np.array([[4, 5, 6],[7, 8, 9],[10,11,12]])
print(a * b) # * 对应位置相乘
print(a @ b) # @ 运用矩阵乘法原理:对应行乘对应列再求和(点积)
'''
a:
1 2 3
4 5 6
7 8 9
b:
4 5 6
7 8 9
10 11 12
矩阵的乘法,如:第一个位置=1*4+2*7+3*10=48
'''
统计运算
NumPy 提供了多种统计函数,如求和,计算平均值,计算中位数,标准差,方差,查找最大值,最小值,计算分位数,累计和,累积差。
a = np.array([[1, 2], [3, 4]])
# 全局求和
total = np.sum(a) # 输出: 10
# 沿轴 0 求和(列方向)
sum_axis0 = np.sum(a, axis=0) # 输出: array([4, 6])
# 沿轴 1 求和(行方向)
sum_axis1 = np.sum(a, axis=1) # 输出: array([3, 7])
# 计算中位数
print(np.median(arr))
# 计算平均值
print(np.mean(arr))
# 计算标准差,方差
# 1,2,3 的平均值为 2
# 方差:((1-2) + (2-2) + (3-2)) / 3 = 0.6666666666
# 标准差(方差开根):根号下0.81649
print(np.var([1, 2, 3])) # 方差
print(np.std([1, 2, 3])) # 标准差
# 计算最大值,最小值
print(arr)
print(np.max(arr), np.argmax(arr)) # 第二个参数返回的是索引值(下标)
print(np.min(arr), np.argmin(arr)) # 第二个参数返回的是索引值(下标)
# 分位数
arr = np.array([155, 160, 165, 168, 170, 172, 175, 178, 180, 185])
print(np.percentile(arr, 20))
'''
分位数的计算方法:
1.确定位置索引:位置 = p * (n - 1),其中 p 是百分比(如20%就是0.2),n是数据总个数。
2.根据位置找到或计算对应的值。
举个例子:还是用那10个身高数据:
[155, 160, 165, 168, 170, 172, 175, 178, 180, 185], n = 10
计算第20百分位数(p=0.2):
1.位置 = 0.2 * (10 - 1) = 0.2 * 9 = 1.8
2.这个位置不是整数,它介于第2个数据(160)和第3个数据(165)之间。
3.使用线性插值法计算:
位置1.8表示:从第2(索引为1)个数据(160)开始,再向第3个数据移动80%的距离。
第2和第3个数据的差值:165 - 160 = 5
移动的距离:5 * 0.8 = 4
第20百分位数的值 = 第2个数据 + 移动距离 = 160 + 4 = 164 cm
'''
# 累计和,累积积
arr = np.array([1, 2, 3])
print(np.cumsum(arr)) # 下标为 i 位置的元素为前 i+1 个元素的和
print(np.cumprod(arr)) # 下标为 i 位置的元素为前 i+1 个元素的积
比较函数
比较是否大于,小于,等于;逻辑与,或,非;检查数组中是否有一个True,是否所有的都是True,自定义条件。
# 是否大于
print(np.greater([3, 4, 5, 6, 7],4))
# 是否小于
print(np.less([3, 4, 5, 6, 7],4))
# 是否等于
print(np.equal([3, 4, 5, 6, 7],4))
# 如果比较双方都是矩阵,则对应位置进行比较.
# 不同规格的矩阵无法进行比较
print(np.equal([1, 2, 3],[4, 2, 1]))
# 逻辑与
print(np.logical_and([1, 0],[1, 1]))
# 逻辑或
print(np.logical_or([1, 0],[0, 0]))
# 逻辑非
print(np.logical_not([1, 0]))
# 检查元素是否至少有一个元素为True
print(np.any([0, 1, 0, 0]))
# 检查是否全部元素为True
print(np.all([1, 1, 0, 1]))
# 自定义条件
# print(np.where(条件,符合条件,不符合条件))
arr = np.array([1, 2, 3, 4, 5])
print(np.where(arr > 3, arr, 0)) # 列表中元素大于 3 的用arr填充,否则用 0 填充
print(np.where(arr > 3, 1, 0)) # 列表中元素大于 3 的用 1 填充,否则用 0 填充
score = np.array([64 72 76 81 51 96 48 75 60 61 58 43 39 72 81 52 51 34 39 66 33 94 68 64
74 32 99 68 79 40])
print(score)
# 嵌套使用
print(np.where(score < 60, '不及格', np.where(
score < 80,'良好','优秀'
)))
# np.select(条件,返回的结果)
print(np.select([score < 60, (score >= 60) & (score <= 80), score > 80],
['不及格', '良好', '优秀'],
default='未知'))
排序函数
排序函数对数组的所有元素进行排序。
# 排序函数
np.random.seed(0) # 固定随机数
arr = np.random.randint(1, 100, 20)
print(arr)
arr.sort() # 这种排序会改变初始 arr
print(arr)
# 固定随机数
np.random.seed(0)
arr = np.random.randint(1, 100, 20)
print(arr)
print(np.sort(arr)) # 这种排序不会改变初始 arr
print(np.argsort(arr)) # 获取索引值
print(arr)
# 去重函数
print(np.unique(arr))
# 数组的拼接
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
print(arr1 + arr2)
print(np.concatenate([arr1, arr2]))
# 数组的分割
print(np.split(arr,5)) # 将数组 arr 切分成 5 等份(注意只能切分成等份,否则会报错)
# 调整数组的形状
print(np.reshape(arr,(4, 5)))
通用函数(ufunc)
NumPy 的通用函数(如 np.sin, np.exp)对数组中的每个元素进行计算,返回新数组。
a = np.array([0, np.pi/2, np.pi])
# 计算正弦值
sin_a = np.sin(a) # 输出: array([0., 1., 0.])
线性代数运算
NumPy 的 linalg 模块提供线性代数运算,如求逆矩阵、特征值等。
a = np.array([[1, 2], [3, 4]])
# 求逆矩阵
inv_a = np.linalg.inv(a) # 输出: array([[-2., 1.], [1.5, -0.5]])
# 特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(a)
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)