Numpy学习笔记分享

NumPy是Python数据分析领域的基础库,以其高效的数组操作和数学计算能力闻名,效率高于list的计算速度。本文基于学习笔记整理,带你快速掌握NumPy的核心功能。如有不足,亲谅解!

import numpy as np

一、Ndarray对象:NumPy的核心数据结构

Ndarray(N-dimensional array)是NumPy中表示多维数组的对象,支持高效的同类型数据存储和计算。

1. Ndarray对象:(类似数学中的行列式)

N维数组对象,是一系列同类型的数据的集合,以0下标开始进行集合中元素的索引。

np.array( list ,dtype=np.数据类型):将列表对象转换为一个数组对象,[  ]则是一维,[ [第一行],[第二行],[……] ]则是二维以此类推。dtype是用来指定存储时候的数据类型。

此处的List对象也可以是range( )生成的序列  np.array( range( n ))

np.arange (起始,结束,步长 ) 直接生成数组对象(一维数组)

ndarray.ndim : 数组的维度

ndarray.shape : 数组的形状(行和列)返回的是元组(行,列)

ndarray.size : 数组的元素数量

ndarray.shape= (行,列),则原来的ndarray对象数组的形状就会发生改变。

ndarray.reshape (  (行,列)  ):改变数组的形状,返回ndarray对象。(行列乘积不可变即元素数量不可改变

ndarray.reshape ( (一维数组的个数,),order=’C’/’F’ ):多维数组转换为一维数组,默认为“C”以行为主的顺序展开,“F”是以列为顺序展开。….flatten (order=’C’/’F’)直接将多维数组转化为一维数组,参数同上理一样。

扩展:(2,3,4):reshape中三维数组传入的参数,2代表块数(所包含的二维数组数),3是行,4是列。

       Ndarray.tolist ( ):将数组转换为一个列表并返回

import numpy as np

# 从列表创建一维/二维数组
arr1 = np.array([1, 2, 3])          # 一维数组
arr2 = np.array([[1, 2], [3, 4]])   # 二维数组

# 使用arange生成连续序列
arr_arange = np.arange(0, 10, 2)    # [0, 2, 4, 6, 8]
print(arr2.ndim)    # 维度:2
print(arr2.shape)   # 形状:(2, 2)
print(arr2.size)    # 元素总数:4
# reshape需保持元素总数不变
arr_reshaped = arr2.reshape(4)      # 转换为1x4数组:[1, 2, 3, 4]

# 直接修改shape属性(谨慎使用)
arr2.shape = (4,)                   # 原数组变为一维

 

2. Ndarray数据类型:数值数据,包括整型,浮点型,复数(complex),布尔数

Int8,uint8(无符号数)  int16/64,uint16/64  float16/32/64/128  complex64/128/256   bool

二、数组操作进阶

1. 数组计算

  • 广播机制:由于Numpy的广播机制在运算过程中,加减乘除的值广播到所有的元素上面。即数组的加减乘除是内部所有元素本身的加减乘除。

 

arr = np.array([1, 2, 3])
print(arr * 2)    # [2, 4, 6]

 

  • 数组间运算:同形状的数组对应位置进行计算操作,不同形状的多维数组是不可以进行计算的。但多维数组与一维数组进行计算是可以的,此时是多维数组每一行数据都与一维数组计算(行相同每一行计算,列相同每一列计算)。

2. 轴(Axis)的概念

  • 二维数组axis=0表示列方向,axis=1表示行方向。

  • 聚合操作示例

arr = np.array([[1, 2], [3, 4]])
print(np.sum(arr, axis=0))   # 列求和:[4, 6]
print(np.mean(arr, axis=1))  # 行均值:[1.5, 3.5]

 

 在二维数组上,如下图上,就像是一个坐标系,对0轴的操作是对上面‘刻度’的上数据操作。

 

 

 通过轴的指定,就可以只对轴上刻度对应的列或行数据单独处理。不指定轴那就是所有数据一起进行计算。三维数组也是同理。

 三维数组要讲究立体感,是对空间上数据进行操作。

在计算的时候可以想象成是每一个坐标轴,分别计算这个轴上面的每一个刻度上的值。

 所以在二维数组中,0是对列的操作,1是对行的操作

三、索引、切片与数值修改 

1. 基础操作

arr = np.array([[1, 2, 3], [4, 5, 6]])

print(arr[1, 0])         # 第2行第1列:4
print(arr[:, 1:3])       # 所有行的第2-3列:[[2,3], [5,6]]

 与切片索引类似,左闭右开

 2. 条件修改

# 使用布尔索引
arr[arr > 3] = 0         # 将大于3的元素置0

最后一个是获取索引1行的所有列

数组[行,列](行与列都可以单独使用切片)

 

 

当取不连续的多行时,使用列表:

import numpy as np
arr1=np.array([1,2,3])
print(arr1[[0,2]]) #[1 3]

四、数组的数值修改

1. 数值修改操作:

 

import numpy as np

# 初始化一个4x6的数组
t = np.arange(24).reshape(4,6)

# 1. 修改单行/单列
t[1, :] = 0      # 修改第2行的所有列
t[:, 1] = 0      # 修改所有行的第2列

# 2. 修改连续多行/多列
t[1:3, :] = 0    # 修改第2-3行的所有列
t[:, 1:4] = 0    # 修改所有行的第2-4列

# 3. 修改子矩阵(多行多列)
t[1:4, 2:5] = 0  # 修改第2-4行、第3-5列区域

# 4. 修改不连续的点(通过坐标列表)
t[[0,1], [0,3]] = 0  # 修改(0,0)和(1,3)位置的值

# 5. 条件修改(布尔索引)
t[t < 10] = 0     # 将所有小于10的值置0

数组的逻辑运算符:&,|,~

​​import numpy as np
t=np.array([1,2,3,4,5,6,7,8,9])
t[(t>2)&(t<8)] #与
t[(t>2)|(t<8)] #或
t[~(t>2)&(t<8)] #非

 

针对np数组的三目运算符: 

 

 五、数组的增删与去重

numpy.append函数:

import numpy as np

# 初始化数组
a = np.array([[1,2,3], [4,5,6]])

# 1. 默认不指定轴(结果展平为一维数组)
print("向数组添加元素(默认展平):")
print(np.append(a, [7,8,9]))  # 输出:[1 2 3 4 5 6 7 8 9]

# 2. 沿轴0添加(行方向,需列数一致)
print("\n沿轴0添加元素:")
print(np.append(a, [[7,8,9]], axis=0))  
# 输出:
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]

# 3. 沿轴1添加(列方向,需行数一致)
print("\n沿轴1添加元素:")
print(np.append(a, [[5,5,5], [7,8,9]], axis=1))  
# 输出:
# [[1 2 3 5 5 5]
#  [4 5 6 7 8 9]]

0添加行,1添加列 

numpy.insert函数:

import numpy as np

# 初始化数组
a = np.array([[1,2], [3,4], [5,6]])

# 1. 未指定轴(先展平再插入)
print("未传递 Axis 参数(展平后插入):")
print(np.insert(a, 3, [11,12]))  # 在索引3位置插入11,12
# 输出:[ 1  2  3 11 12 4 5 6]

# 2. 沿轴0插入(行方向)
print("\n沿轴0广播插入:")
print(np.insert(a, 1, [11], axis=0))  # 在第1行插入[11, 11](自动广播)
# 输出:
# [[ 1  2]
#  [11 11]
#  [ 3  4]
#  [ 5  6]]

# 3. 沿轴1插入(列方向)
print("\n沿轴1广播插入:")
print(np.insert(a, 1, 11, axis=1))  # 在第1列插入11
# 输出:
# [[ 1 11  2]
#  [ 3 11  4]
#  [ 5 11  6]]

numpy.delete 函数:删除数组元素或子数组

函数说明

  • 功能:返回从输入数组中删除指定子数组的新数组。

  • 关键参数

    • arr:输入数组。

    • obj:要删除的索引、切片或索引列表。

    • axis:指定删除的轴,默认为 None(展平后操作)。

import numpy as np

# 初始化一个3x4的数组
a = np.arange(12).reshape(3, 4)
print("第一个数组:")
print(a)
# 输出:
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]

# 1. 未指定轴(先展平后删除第5个元素)
print("\n未传递 Axis 参数(展平后删除):")
print(np.delete(a, 5))  
# 输出:[ 0  1  2  3  4  6  7  8  9 10 11](删除了索引5的元素5)

# 2. 沿轴1删除列(删除每一行的第2列)
print("\n删除每一行中的第二列:")
print(np.delete(a, 1, axis=1))  
# 输出:
# [[ 0  2  3]
#  [ 4  6  7]
#  [ 8 10 11]]

 2. 去重

numpy.unique 函数:数组去重与索引映射

函数说明

  • 功能:返回去重后的数组,并支持返回原数组的索引、反向索引和元素计数。

  • 关键参数

    • return_index:返回去重元素在原数组中的首次出现位置。

    • return_inverse:返回原数组元素在去重数组中的索引。

    • return_counts:返回去重元素在原数组中的出现次数。

 

import numpy as np

# 初始化数组
a = np.array([5, 2, 6, 2, 7, 5, 6, 8, 2, 9])
print("第一个数组:")
print(a)  # 输出:[5 2 6 2 7 5 6 8 2 9]

# 1. 基本去重
u = np.unique(a)
print("\n去重后的数组:")
print(u)  # 输出:[2 5 6 7 8 9]

# 2. 返回去重元素的首次出现索引
u, indices = np.unique(a, return_index=True)
print("\n去重元素在原数组中的首次出现索引:")
print(indices)  # 输出:[1 0 2 4 7 9]
# 解释:2首次出现在索引1,5在索引0,6在索引2,依此类推

# 3. 返回反向索引(原数组元素在去重数组中的位置)
u, inverse = np.unique(a, return_inverse=True)
print("\n原数组元素在去重数组中的索引:")
print(inverse)  # 输出:[1 0 2 0 3 1 2 4 0 5]

# 4. 返回元素出现次数
u, counts = np.unique(a, return_counts=True)
print("\n去重元素的出现次数:")
print(counts)  # 输出:[3 2 2 1 1 1]
# 解释:2出现3次,5出现2次,依此类推

六、数学计算与统计

一、统计函数

 1. 极值计算:np.max / np.min

import numpy as np

score = np.array([[80, 88], [82, 81], [75, 81]])

# 全局最大值
max_all = np.max(score)        # 88

# 沿轴0(列方向)的最大值
max_axis0 = np.max(score, axis=0)  # [82, 88]

# 全局最小值
min_all = np.min(score)        # 75

# 沿轴0(列方向)的最小值
min_axis0 = np.min(score, axis=0)  # [75, 81]

2. 均值与标准差

# 全局均值
mean_all = np.mean(score)       # 81.0

# 沿轴0(列方向)的均值
mean_axis0 = np.mean(score, axis=0)  # [79.0, 83.0]

# 沿轴0(列方向)的标准差
std_axis0 = np.std(score, axis=0)    # [3.60555128, 3.60555128]

3. 极差计算:np.ptp 

# 全局最大值与最小值的差(极差)
range_all = np.ptp(score)       # 13(88-75)

# 沿轴0的极差
range_axis0 = np.ptp(score, axis=0)  # [7, 7]

4. 索引获取:np.argmin / np.argmax 

# 沿轴0的最小值索引
argmin_axis0 = np.argmin(score, axis=0)  # [2, 2](第3行的索引为2)

二、累计操作与广播

1. 累计和:np.cumsum

arr = np.array([[1, 2, 3], [4, 5, 6]])

# 沿轴0(列方向)累计和
cumsum_axis0 = arr.cumsum(axis=0)
# [[1, 2, 3],
#  [5, 7, 9]](第二行=原第一行+第二行)

# 沿轴1(行方向)累计和
cumsum_axis1 = arr.cumsum(axis=1)
# [[1, 3, 6],
#  [4, 9, 15]]

2. 元素级比较:np.maximum / np.minimum

# 元素级比较(支持广播)
result1 = np.maximum([-2, -1, 0, 1, 2], 0)  # [0, 0, 0, 1, 2]
result2 = np.minimum([-2, -1, 0, 1, 2], 0)  # [-2, -1, 0, 0, 0]
result3 = np.maximum([-2, 5, 0], [1, 2, 3])  # [1, 5, 3]

三、通用数学函数

1. 基础运算

arr = np.array([4, 9, 16])

# 平方根
sqrt_arr = np.sqrt(arr)          # [2., 3., 4.]

# 平方
square_arr = np.square(arr)      # [16, 81, 256]

# 绝对值
abs_arr = np.abs(np.array([-1, -2, 3]))  # [1, 2, 3]

# 指数
exp_arr = np.exp([1, 2, 3])      # [2.718, 7.389, 20.085]

2. 对数与取整

# 自然对数
log_arr = np.log([1, np.e, np.e**2])  # [0, 1, 2]

# 向上取整
ceil_arr = np.ceil([1.2, 2.5, 3.7])   # [2., 3., 4.]

# 向下取整
floor_arr = np.floor([1.2, 2.5, 3.7]) # [1., 2., 3.]

# 四舍五入
rint_arr = np.rint([1.2, 2.5, 3.7])   # [1., 2., 4.]

3. 三角函数与符号处理

# 正弦值
sin_arr = np.sin(np.pi/2)        # 1.0

# 符号分离(整数和小数部分)
frac, int_part = np.modf([1.5, 2.3])  # frac=[0.5, 0.3], int_part=[1., 2.]

# 符号复制
copysign_arr = np.copysign([1, -2, 3], [-1, 1, -1])  # [-1, 2, -3]

四、元素级运算与逻辑比较

1. 算术运算

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

# 元素级加减乘除
add = np.add(a, b)        # [5, 7, 9]
subtract = np.subtract(b, a)  # [3, 3, 3]
multiply = np.multiply(a, b)  # [4, 10, 18]
divide = np.divide(b, a)      # [4.0, 2.5, 2.0]

 2. 逻辑比较

x = np.array([1, 3, 5])
y = np.array([2, 3, 4])

# 元素级比较
greater = np.greater(x, y)        # [False, False, True]
equal = np.equal(x, y)            # [False, True, False]

# 逻辑运算
logical_and = np.logical_and(x > 2, y < 4)  # [False, True, False]

 

 七、数组的拼接

1.np.concatenate:沿指定轴拼接数组
import numpy as np

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])

# 沿轴0(行方向)拼接
result_axis0 = np.concatenate((a, b), axis=0)
# 输出:
# [[1 2]
#  [3 4]
#  [5 6]
#  [7 8]]

# 沿轴1(列方向)拼接
result_axis1 = np.concatenate((a, b), axis=1)
# 输出:
# [[1 2 5 6]
#  [3 4 7 8]]
2. np.stack:创建新维度堆叠数组
# 沿新维度(轴0)堆叠
stack_axis0 = np.stack((a, b), axis=0)
# 输出形状:(2, 2, 2)
# [[[1 2]
#   [3 4]]
#  [[5 6]
#   [7 8]]]

# 沿列方向(轴1)堆叠
stack_axis1 = np.stack((a, b), axis=1)
# 输出形状:(2, 2, 2)
# [[[1 2]
#   [5 6]]
#  [[3 4]
#   [7 8]]]
3. 快速拼接函数:vstackhstack
v1 = np.array([[0,1,2,3,4,5], [6,7,8,9,10,11]])
v2 = np.array([[12,13,14,15,16,17], [18,19,20,21,22,23]])

# 垂直拼接(等价于axis=0的concatenate)
result_v = np.vstack((v1, v2))
# 输出:
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]

# 水平拼接(等价于axis=1的concatenate)
result_h = np.hstack((v1, v2))
# 输出:
# [[ 0  1  2  3  4  5 12 13 14 15 16 17]
#  [ 6  7  8  9 10 11 18 19 20 21 22 23]]

 八、数组的分割

1.使用np.split()函数分割数组

np.split()函数是Numpy库中用于分割数组的一个非常强大的工具。它允许你按照指定的轴和位置(或数量)来分割数组。

import numpy as np
 
# 创建一个3x3的数组
arr = np.arange(9).reshape(3, 3)
print("原数组:")
print(arr)
 
# 将数组分为三个大小相等的子数组(沿着默认轴0,即横向分割)
b = np.split(arr, 3)
print("\n将数组分为三个大小相等的子数组:")
for i, sub_arr in enumerate(b):
    print(f"子数组 {i+1}:\n{sub_arr}")

原数组:
[[0 1 2]
 [3 4 5]
 [6 7 8]]
 
将数组分为三个大小相等的子数组:
子数组 1:
[[0 1]
 [3 4]]
子数组 2:
[[2]]
子数组 3:
[[5 6]
 [7 8]]

注意:在上面的代码中,由于数组arr的形状是3x3,而我们要将其分割成3个子数组,因此最后一个子数组的形状与其他两个不同。这是因为np.split()函数在分割时会尽量保持每个子数组的大小相等,但如果无法完全平均分割,则会创建一个形状不同的子数组来容纳剩余的元素。

另外,np.split()函数还可以接受一个整数数组作为indices_or_sections参数,以指定分割的具体位置。例如,np.split(arr, [1, 2])会将数组arr在索引1和2处分割成三个子数组。

2. 使用numpy.hsplit()函数水平分割数组

numpy.hsplit()函数是专门用于水平分割数组的函数,即沿着轴0(横向)分割。它接受一个数组和一个整数作为参数,指定要返回的相同形状的数组数量。

# 创建一个2x6的随机数组
harr = np.floor(10 * np.random.random((2, 6)))
print("\n原数组:")
print(harr)
 
# 将数组水平分割成3个子数组
split_harr = np.hsplit(harr, 3)
print("\n拆分后:")
for i, sub_arr in enumerate(split_harr):
    print(f"子数组 {i+1}:\n{sub_arr}")
注意:

由于np.random.random()生成的是随机浮点数,因此每次运行代码时得到的数组都会不同。上面的代码示例中使用了np.floor()函数来将浮点数向下取整,以便得到整数数组。

 

3. 使用numpy.vsplit()函数垂直分割数组

numpy.vsplit()函数与numpy.hsplit()函数类似,但它是用于垂直分割数组的函数,即沿着轴1(纵向)分割。

 

# 创建一个4x4的数组
a = np.arange(16).reshape(4, 4)
print("\n原数组:")
print(a)
 
# 将数组垂直分割成2个子数组
split_a = np.vsplit(a, 2)
print("\n拆分后:")
for i, sub_arr in enumerate(split_a):
    print(f"子数组 {i+1}:\n{sub_arr}")

 九、数组中的nan和inf

1. nan代表的是空值,inf代表的是无穷值(无穷大/无穷小)

因为np.nan!=np.nan返回的是真(1),np.nan==np.nan返回的是假(0),那么我们就可以让数组与自身比较,不相等时返回的是真值,说明此处是nan。

当一列数据有nan时,如果需要它来计算,则可以替换为平均值。

t.shape返回的是形状,是由元组构成(行,列),此处是获取列数。

np.count_nonzero()返回数组中非0的个数,此处如果不是返回0就说明有nan。

十、数组的转置(a.T)

 

 

### NumPy 学习笔记及相关教程 NumPyPython 中用于科学计算的核心库之一,提供了强大的多维数组对象以及一系列派生工具。以下是有关 NumPy学习要点及其应用实例: #### 1. 基本操作 NumPy 提供了多种创建和操作数组的方法。例如,可以通过 `np.array` 创建一个多维数组并对其进行加法运算[^2]: ```python import numpy as np a = np.array([[3,4,5,6,7,8], [4,5,6,7,8,9]]) b = 2 a = a + b print(a) ``` #### 2. 高级索引技术 布尔索引是一种非常实用的功能,允许基于条件筛选数据。以下是一个简单的例子[^3]: ```python y = np.arange(35).reshape(5, 7) filtered_y = y[y > 20] # 获取 y 中值大于 20 的元素 range_filtered_y = y[(y > 5) & (y < 10)] # 获取 y 中介于 5 和 10 之间的元素 nan_array = np.array([np.nan, 1, 2, np.nan, 3, 4, 5]) cleaned_nan_array = nan_array[~np.isnan(nan_array)] # 移除 NaN 值 ``` #### 3. 列向量转换技巧 对于一维数组,默认情况下它是行向量。如果需要将其转化为列向量,则需使用特定方法而非简单转置[^4]: ```python arr = np.array([1, 2, 3]) column_vector_1 = arr[:, None] column_vector_2 = arr.reshape((len(arr), 1)) ``` #### 4. 数学函数支持 NumPy 支持广泛的数学运算功能,包括但不限于三角函数、指数对数等基本算术操作。 --- ### 推荐的学习资源 为了更深入地掌握 NumPy,可以参考以下几种途径: - **官方文档**: 官方网站提供详尽的 API 文档与教程。 - **在线课程平台**: 如 Coursera 或 edX 上有专门针对 NumPy 的入门至高级课程。 - **书籍推荐**: - *Python for Data Analysis* by Wes McKinney. - *Numerical Python: A Practical Techniques Approach for Industry.* 这些材料能够帮助初学者逐步理解核心概念,并通过实践巩固所学技能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值