【无痛学Python】NumPy基础,看这一篇就够了!

【Python数据分析】NumPy基础,看这一篇就够了!

NumPy的简介与意义

NumPy是Python的一种开源的数值计算扩展库,包含很多功能,如创建n维数组(矩阵)、对数组进行函数计算、数学计算等等。

使用import numpt as np进行导入。

标准的Python用List(列表)保存值,可以当作数组使用,但是因为列表中元素可以是任何对象,就导致了CPU运算时间和内存会大大增长。NumPy的出现弥补了这一缺点,它提供了两种基本的对象:

  • ndarray:存储单一数据类型的多维数组
  • ufunc:一种能够对数组进行处理的函数

这两种对象完美解决了由于任何对象带来的时间和空间的问题,大大提高了运行效率。

NumPy多维数组

创建数组对象

1.使用array创建数组对象

使用array函数进行数组对象的创建。

array(object,dtype,ndmin)

object:想要创建的数组名

dtype:所需的数据类型,未给定则选择保存对象所需的最小类型,默认为None

ndmin:接收int,指定最小维度n,默认为None

# 创建数组对象
data1 = [1,2,3,4] # 列表
w1=np.array(data1)
print(w1)
data2 = (1,2,3,4) # 元组
w2=np.array(data2)
print(w2)
data3 = [[1,2,3,4],[5,6,7,8]] # 多维数组
w3=np.array(data3)
print(w3)

NumPy是自动判断最合适的数据类型,并保存在dtype中。

w4=np.array([1,2.1,3,4.5])
print(w4.dtype)
# 结果是:float64

2.专门创建数组的函数

上述效率也太慢了,每次都要自己先建个已有序列。NumPy中由专门的函数来创建数组

  • arange

    类似于range,可指定起始值、终止值、步长,创建的数组不包含终止值

    warray1 = np.arange(1,2,0.2)
    print(warray1) # [1.  1.2 1.4 1.6 1.8]
    warray2 = np.arange(10)
    print(warray2) # [0,1,2,3,4,5,6,7,8,9]
    
  • linspace

    若数据类型是浮点型,则由于精度原因不太可能区预测获得元素的数量,所以会选择linspace

    指定起始值,终止值,元素个数(这里和arange不一样),并且默认是包含终止值的。

    warray3 = np.linspace(0,1,5)
    print(warray3) # [0.   0.25 0.5  0.75 1.  ]
    
  • logspace

    它与linspace类似,但是是创建等比数列

    warray4 = np.logspace(0,1,5)
    print(warray4) # [ 1.          1.77827941  3.16227766  5.62341325 10.        ]
    
  • zeros

    创建指定长度或形状的全0数组

    warray5 = np.zeros(4)
    print(warray5) # [0. 0. 0. 0.]
    
  • ones

    创建指定长度或形状的全1数组

    warray6 = np.ones(4)
    print(warray6) # [1. 1. 1. 1.]
    
  • diag

    创建对角矩阵,即对角线元素为指定值或者0,其他元素为0

    warray7 = np.diag([1,2,3,4])
    print(warray7)
    # [[1 0 0 0]
    # [0 2 0 0]
    # [0 0 3 0]
    # [0 0 0 4]]
    

ndarray对象属性和数据转换

属性

主要包括以下属性:

属性说明
ndim数据轴的个数
shape数组的维度/形状
size元素个数
dtype数据类型
itemsize每个元素的字节大小
warray = np.array([[1,2,3],[4,5,6]])
print('秩为:',warray.ndim)
print('形状为:',warray.shape)
print('元素个数为:',warray.size)

数组的shape等属性可以自己设置。

warray.shape = 3,2
print(warray) 
# [[1 2]
# [3 4]
# [5 6]]

生成随机数

格式:np.random

通常根据数据类型来进行随机数的生成。例如:

np.random.randint(low,high = None,size = None) # 生成指定范围内的随机整数

suijishu = np.random.randint(100,200,size = (2,4)) # 生成指定范围内的随机整数
print(suijishu)
# [[160 147 112 147]
# [126 168 156 138]]

因为是随机数生成,所以可能每次生成都不一样,可以使用seed来确定一个种子。

数组变换

1.数组重塑

使用reshape改变维度,传入的参数为新维度的元组。

其中有一个参数可以设置为-1,表是数组的维度可以通过数据本身进行自动推断。

arr1 = np.arange(8)
print(arr1)
# [0 1 2 3 4 5 6 7]
arr2 = arr1.reshape(4,2)
print(arr2)
# [[0 1]
# [2 3]
# [4 5]
# [6 7]]
arr3 = arr1.reshape(2,-1)
print(arr3)
# [[0 1 2 3]
# [4 5 6 7]]

# 数据展开
arr4 = arr3.ravel()
print(arr4)
# [0 1 2 3 4 5 6 7]

2.数组合并

合并是多个数组之间的操作,分为横向合并hstack,纵向合并vstackconcatenate函数自定义合并

arr1 = np.arange(8)
print(arr1)
arr2 = arr1*2
print(arr2)
# 使用hstack
arr5 = np.hstack((arr1,arr2))
print(arr5)
# 使用vstack
arr6 = np.vstack((arr1,arr2))
print(arr6)
# concatenate的参数axis=1是横向合并,axis=0是纵向合并
arr7 = np.concatenate((arr1,arr2),axis = 1) # 横向合并
arr8 = np.concatenate((arr1,arr2),axis = 0) # 纵向合并

3.数组分割、转置和轴兑换

分割:hsplit 横向、vsplit纵向,split指定方向(与concatenate一样的规则)

转置:transpose需要传入轴编号组成的元组、T属性直接进行转置

轴变换:swapaxes

数组的索引和切片

数据分析经常会选取符合条件的数据,NumPy通过数组的索引和切片进行数组元素的选取。

索引和切片操作不会影响原来的数组。

一维数组

# 索引
arr = np.arange(10)
print(arr) # [0 1 2 3 4 5 6 7 8 9]
print(arr[2]) # 2
print(arr[-1]) # 9
# 切片
print(arr[1:4]) # [1,2,3]
# 数组元素的复制
arr1 = arr[-4:-1].copy()
print(arr1) # [6 7 8]

多维数组

对于多维数组,每个维度都会有一个索引,各个维度的索引之间使用逗号分隔。

# 多维数组的索引
arr = np.arange(12).reshape(3,4)
print(arr)
# [[ 0  1  2  3]
# [ 4  5  6  7]
# [ 8  9 10 11]]
print(arr[1,1:3]) # [5 6]
print(arr[:,2]) # [2 6 10]
print(arr[:1,:1]) # [[0]]

数组的运算

数组运算支持向量化运算。将本来需要在Python级别进行的运算放到C语言运算中,会显著提高运算速度。

数组和标量间的运算

相同维度的数组的算术运算可以直接运用到元素中。

ufunc函数

全称为通用函数,是一种能够针对数组中的所有元素进行操作的函数。

ufunc函数以NumPy数组作为输出。

常用的ufunc函数运算

  • 四则运算:加减乘除。形状必须相同,否则无法进行运算。
# 四则运算
x = np.array([1,2,3])
y = np.array([4,5,6])
z = np.array([7,8,9,10])
print(x+y) # [5 7 9]
print(x+z) # 出错

image-20250507223329047

  • 比较运算:返回的结果是一个布尔数组,每个元素都是每个数组对应元素的比较结果。
x = np.array([1,2,3])
y = np.array([4,5,6])
print(x<y)
# [ True  True  True]
  • 逻辑运算:np.any表示逻辑“or”,np.all表示逻辑“and”,运算结果返回布尔值。

ufunc函数的广播机制

鉴于可能会有不同形状的数组进行算术运算,有以下四条广播机制原则:

  • 所有输入数组向shape最长的数组看齐,shape中不足的部分通过在前面加1进行补齐
  • 输出数组的shape是输入数组shape的各个轴上的最大值
  • 若输入数组的某个轴和输出数组的对应轴的长度相同或者其长度为1时,这个数组能够用来计算,否则出错
  • 输入数组的某个轴长度为1时,沿着此轴运算时都用此轴上的第一组值

逻辑运算

可以使用基本逻辑运算来进行实现,但效率不高;

使用where方法来克服:

np.where(condition,x,y)

若满足条件condition则输出x,否则输出y。

若没有x和y,则默认输出满足条件元素的坐标。

数组读/写

读/写二进制文件

NumPy提供了多种文件操作函数存取数组内容。存取格式分为两类:二进制和文本。

二进制格式又分为NumPy专用的格式化二进制类型和无格式类型。

以下是二进制文件读/写的两种方法:

  • NumPy.load("文件名.npy"):从二进制文件中读取数据
  • NumPy.save("文件名[.npy]",arr):以二进制格式保存数据
a = np.arange(1,13).reshape(3,4)
print(a)
np.save("arr.npy",a)
c = np.load("arr.npy")
print(c)

读/写文本文件

有以下几种主要方法:

  • NumPy.loadtxt(".txt",delimiter=","):把文件加载到一个二维数组中。
  • NumPy.savetxt(".txt",arr,fmt="%d",delimiter=","):把数组写到某种分隔符隔开的文本文件中
  • NumPy.genfromtxt(".txt",delimiter=","):结构化数组和缺失数据

读取CSV文件

读取CSV文件格式:

loadtxt(fname ,dtype =, comments = '#', delimiter = None, skiprows = 0, usecols = None, unpack = False, ndmin = 0, encoding = 'bytes')

主要参数及其说明见下表:

参数说明
fnamestr,读取的CSV文件名
delimiterstr,数据的分隔符
usecolstuple(元组),执行加载数据文件中的哪些列
unpackbool,是否将加载的数据拆分为多个组,Ture表示拆,False表示不拆
skiprowsint,跳过多少行,一般用于跳过描述性文字
encodingbytes,编码格式

NumPy中的数据统计和分析

由于比Python直接进行数组运算要快得多,NumPy通常作为Python数据统计与分析的首选。

排序

排序方式分为直接排序和间接排序。

  • 直接排序:对数据直接进行排序,通常使用sort函数进行实现
  • 间接排序:根据一个或多个键值对数据集进行排序,通常使用argsortlexsort函数进行实现

直接排序

numpy.sort(a,axis,kind,order)

参数说明
a要排序的数组
axis=1时是沿横轴进行排序;=0时是沿纵轴进行排序;=None时是将数组平坦化后进行排序
kind排序的算法类型,默认是快速排序(这里主要是针对不同的数组进行效率的匹配)
order若数组包含字段,这里就是要排序的字段
# 数组的排序
# 直接排序
arr1 = np.array([1,2,5,3,7,5,3,45])
arr1.sort()
print(arr1)
# [ 1  2  3  3  5  5  7 45]
arr2 = np.array([[1,3,5,6],[5,2,3,77],[4,3,6,7]])
arr2.sort(axis = 1)
print(arr2)
# [[ 1  3  5  6]
# [ 2  3  5 77]
# [ 3  4  6  7]]
arr3 = np.array([[1,3,5,6],[5,2,3,77],[4,3,6,7]])
arr3.sort(axis = 0)
print(arr3)
# [[ 1  2  3  6]
# [ 4  3  5  7]
# [ 5  3  6 77]]

间接排序

使用argsortlexsort可以在给定一个或多个键的时候得到一个由整数构成的索引数组。

也就是说可以返回原先数组元素在排序后数组的具体位置。

argsort

# 一维数组排序
a = np.array([3, 1, 4, 1, 5, 9, 2, 6])
idx = np.argsort(a)
print("一维数组排序后的索引:", idx)
print("排序后的数组:", a[idx])

# 二维数组按列排序
b = np.array([[3, 1, 4], [1, 5, 9], [2, 6, 5]])
idx2 = np.argsort(b, axis=1)  # 按行排序
print("\n二维数组每行排序后的索引:\n", idx2)

一维数组排序后的索引: [1 3 6 0 2 4 7 5]
排序后的数组: [1 1 2 3 4 5 6 9]

二维数组每行排序后的索引:
 [[1 0 2]
 [0 1 2]
 [0 2 1]]

lexsort(keys,axis)

  • keys:排序的键数组或元组,按最后一个键优先排序,先对前面的键排序

  • axis:指定排序的轴,默认是最后一个轴

# 按两组键排序
names = np.array(['Alice', 'Bob', 'Alice', 'Bob', 'Alice'])
ages = np.array([25, 20, 30, 25, 20])

# 按名字先排序,再按年龄排序
idx = np.lexsort((ages, names))
print("\n按名字和年龄排序后的索引:", idx)
print("排序结果:")
print("名字:", names[idx])
print("年龄:", ages[idx])
按名字和年龄排序后的索引: [4 0 2 1 3]
排序结果:
名字: ['Alice' 'Alice' 'Alice' 'Bob' 'Bob']
年龄: [20 25 30 20 25]
最终排序如下:
(Alice, 20)(Alice, 25)(Alice, 30)(Bob, 20)(Bob, 25)

重复数据与去重

在数据统计与分析中,数据去重是一个很重要的事情。在NumPy中,使用unique(中文翻译过来也就是独一无二)来进行去重。

numpy.unique(arr, return_index=False, return_inverse=False, return_counts=False, axis=None)

参数说明
arr输入数组
return_index是否返回去重后元素的首次出现位置
return_inverse是否返回对应位置索引
return_counts是否返回每个唯一元素的出现次数
axis指定轴
a = np.array([3, 3, 4, 2, 2, 1, 5, 5, 5, 1])

# 基本去重
unique_elements = np.unique(a)
print("去重后的元素:", unique_elements)

# 返回元素出现位置和出现次数
unique_elements, indices, inverse, counts = np.unique(a, return_index=True, return_inverse=True, return_counts=True)
print("\n唯一元素:", unique_elements)
print("首次出现的位置:", indices)
print("在唯一数组中的对应位置:", inverse)
print("出现次数:", counts)

np.tile(A,reps)

A指的是待扩展的数组;

reps指的是扩展次数。

# 一维数组
a = np.array([1, 2, 3])
tiled_1d = np.tile(a, 3)
print("\n一维数组扩展:", tiled_1d)
# [1 2 3 1 2 3 1 2 3]
# 二维数组
b = np.array([[1, 2], [3, 4]])
tiled_2d = np.tile(b, (2, 3))
print("\n二维数组扩展:\n", tiled_2d)
# [[1 2 1 2 1 2]
# [3 4 3 4 3 4]
# [1 2 1 2 1 2]
# [3 4 3 4 3 4]]

np.repeat(a,reps,axis = None)

# 一维数组
c = np.array([1, 2, 3])
repeated_1d = np.repeat(c, 3)
print("\n一维数组重复:", repeated_1d)
# [1 1 1 2 2 2 3 3 3]

# 二维数组
d = np.array([[1, 2], [3, 4]])
repeated_2d = np.repeat(d, 2, axis=0)
print("\n二维数组按行重复:\n", repeated_2d)
# [[1 2]
# [1 2]
# [3 4]
# [3 4]]
repeated_2d_col = np.repeat(d, 2, axis=1)
print("\n二维数组按列重复:\n", repeated_2d_col)
# [[1 1 2 2]
# [3 3 4 4]]

常用统计函数

常用的统计分析函数有以下这些,可自行查看用法。

函数功能示例
np.sum计算数组元素的总和np.sum(arr)
np.mean计算均值np.mean(arr)
np.median计算中位数np.median(arr)
np.var计算方差np.var(arr)
np.std计算标准差np.std(arr)
np.min计算最小值np.min(arr)
np.max计算最大值np.max(arr)
np.ptp计算极差(最大值 - 最小值)np.ptp(arr)
------------------------------------------------------
np.sum计算数组元素的总和np.sum(arr)
np.mean计算均值np.mean(arr)
np.median计算中位数np.median(arr)
np.var计算方差np.var(arr)
np.std计算标准差np.std(arr)
np.min计算最小值np.min(arr)
np.max计算最大值np.max(arr)
np.ptp计算极差(最大值 - 最小值)np.ptp(arr)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Skrrapper

谢谢你的支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值