Python数据处理工具笔记 - matplotlib, Numpy, Pandas

matplotlib, Numpy, Pandas

由于有很多例子是需要运算后的图表看着更明白一些,很明显csdn不支持
所以用谷歌的Colab(可以理解为白嫖谷歌的云端来运行的jupyter notebook)来展示:
Colab链接(需要梯子):Python数据挖掘

当然如果实在没有梯子,那就凑合着往下看吧,我也懒得整理格式了(

目录一览:

请添加图片描述
请添加图片描述

正文

1.配置环境

1.1 基础包安装

pip install matplotlib
pip install numpy
pip install pandas
pip install jupyter

1.2 作用

  1. matplotlib: 画图
  2. numpy: 运算
  3. pandas: 数据处理
  4. jupyter:笔记/展示

2.Matplotlib画图

2.1 什么是matplotlib

  • 开发2D图表,简单,渐进交互式实现数据可视化
  • js(D3/echarts)同样可以实现可视化,但根据奥卡姆剃刀原理:如无必要勿增实体,给自己看不需要那么复杂。
  • matplotlib官方文档

2.2 图像包含的信息以及具体描述

图片

2.3 Matplotlib三层结构

1. 容器层(Container Layer)

容器层是最底层,提供了图表的物理容器:

  • 画板层(Canvas): 是最底层的容器,代表了绘图的物理表面。在显示器或其他设备上,它是实际绘制图形的地方,但通常不需要直接与之交互。
  • 画布层(Figure): plt.figure()用于创建一个画布,在这个画布上可以添加一个或多个绘图区(Axes)。Figure是最顶层的容器,用于包含图表中的所有元素。
  • 绘图区/坐标系(Axes): plt.subplots()用于在Figure上添加绘图区,这是实际绘制图形的地方,每个Axes对象可以看作是一个独立的图表。

2. 辅助显示层(Artist Layer)

这一层包括了图表中的所有可视化元素,除了基本的图像以外,还有用于增强理解的辅助图形,例如:

  • 标题(Title): 图表的标题,用于简要说明图表的主题。
  • 图例(Legend): 用于解释图表中的符号或颜色。
  • 网格(Grid): 背景上的网格线,用于更好地量化图表中的数据点。
  • 坐标轴(Axis): 包括坐标轴本身和坐标轴标签,用于显示数据的尺度和单位。
  • 刻度(Ticks)刻度标签(Tick Labels): 轴上的刻度和对应的标签,用于标识数据的具体值。

3. 图像层(Rendering Layer)

图像层是最顶层,用于绘制图表中的数据点,包括:

  • 线条(Line plots): 用于绘制线图。
  • 散点(Scatter plots): 用于绘制散点图。
  • 柱状图(Bar charts): 用于绘制柱状图。
  • 等高线图(Contour plots): 用于绘制等高线图。
  • 图像(Images): 直接在图表中显示图像。

2.4 各种图的应用场景

1. 折线图(Line Plot)(时间变化)

作用:折线图主要用于展示数据随时间或有序类别变化的趋势。它通过将数据点按顺序连接起来的线条表示,非常适合用于显示数据如何在一段时间内变化,比如股票价格的波动、气温的变化等。

特点

  • 优秀的时间序列数据展示工具。
  • 易于识别趋势和模式。

2. 散点图(Scatter Plot)(关系/规律)

作用:散点图用于展示两个(或更多)变量之间的关系,每个数据点在图表中由其在两个轴上的值确定。它是研究变量之间是否存在相关性的好方法,比如身高和体重的关系。

特点

  • 显示变量之间的相关性
    • 正相关:当一个变量增加时,另一个变量也增加。
    • 负相关:当一个变量增加时,另一个变量减少。
    • 无相关:两个变量之间没有明显的线性关系。
  • 识别数据集中的异常值。

3. 柱状图(Bar Chart)(统计/对比)

作用:柱状图通过水平或垂直的柱子长度来显示不同类别间的比较。每个柱子代表一个类别,柱子的长度表示该类别的数值大小。柱状图非常适合比较多个类别之间的数值或展示每个类别随时间的变化。

特点

  • 易于比较不同类别的数值大小。
  • 显示一个或多个类别的数值变化。

4. 直方图(Histogram)(分布情况)

作用:直方图是一种特殊类型的柱状图,用于表示数据的分布情况。与柱状图不同,直方图的每个柱子代表数据在某个区间(或“bin”)的频率或数量,适合用来展示数据集的统计分布,如人群的年龄分布、成绩分布等。

特点

  • 展示数据的分布情况(集中趋势、偏斜和峰度等)。
  • 有助于识别数据的异常值和分布的形状。

和柱状图的区别

  • 柱状的宽在柱状图中没有意义,而直方图有意义。
  • 柱状图不是连续的柱,而直方图是。

5. 饼图(Pie chart) (占比)

作用: 饼图最适合用来展示各部分相对于整体的比例大小。每个扇形的大小按其所代表的数量的比例分配,使得观众可以一目了然地看出各部分之间的比较。饼图通过不同的颜色区分不同的类别,便于观众识别和比较各个类别的占比。

2.5 折线图代码及使用示例

“”"

import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl

Example 1

fig, ax = plt.subplots() # Create a figure containing a single axes.
ax.plot([1, 2, 3, 4], [1, 4, 2, 3]) # Plot some data on the axes.

plt.show()

Example 2

x = np.linspace(0, 2, 100) # 一组list数据

创建画板和绘图区,layout是设定自动调整所有子图参数(xy轴/线…), nrows和ncols是调整有几个绘图区,调用的时候就是ax[n].xxx即可

fig, ax = plt.subplots(figsize=(8, 4), dpi=80, layout=‘constrained’, nrows=1, ncols=1)

三条线

ax.plot(x, x, label=‘linear’, color=‘green’)
ax.plot(x, x2, label=‘quadratic’, color=‘red’)
ax.plot(x, x
3, label=‘cubic’, color=‘#66ccff’)

设置xy轴

ax.set_xlabel(‘x-axis’)
ax.set_ylabel(‘y-axis’)
ax.set_title(“Title”)

添加主刻度/副刻度的网格线,which控制, alpha控制透明度

ax.grid(which=‘major’, color=‘gray’, linestyle=‘-’, linewidth=0.5, alpha=0.5)

设置x轴和y轴的范围

ax.axis([0, 3, 0, 10])

添加一个箭头,以及标注语

ax.annotate(‘end here’, xy=(2, 4), xytext=(2.5, 2.5), arrowprops=dict(facecolor=‘black’, shrink=0.05))

添加legend,也就是显示每条不同的线代表什么的小表格

ax.legend()

注意这里是画布或者画板调用show,而绘图区/坐标轴是无法调用show的

plt.show()

Example 3

x = np.linspace(0, 10, 100) # 生成0-10之间的100个数
y = np.sin(x) # 将x中的数都进行sin取值

plt.plot(x, y)
plt.xticks(ticks=np.arange(0, 11, 2), labels=[‘zero’, ‘two’, ‘four’, ‘six’, ‘eight’, ‘ten’], rotation=45) # 自定义X轴刻度,以及文字斜度
plt.show()

Example 4

x = np.linspace(0, 2, 100) # 一组list数据

创建画板和绘图区,layout是设定自动调整所有子图参数(xy轴/线…), nrows和ncols是调整有几个绘图区,调用的时候就是ax[n].xxx即可

fig, ax = plt.subplots(figsize=(12, 6), dpi=80, layout=‘constrained’, nrows=1, ncols=3)

三条线

titles = [‘linear’, ‘quadratic’, ‘cubic’]
ax[0].plot(x, x, label=titles[0], color=‘green’)
ax[1].plot(x, x2, label=titles[1], color=‘red’)
ax[2].plot(x, x
3, label=titles[2], color=‘#66ccff’)

设置xy轴

for i in range(3):
ax[i].set_xlabel(‘x-axis’)
ax[i].set_ylabel(‘y-axis’)
ax[i].set_title(titles[i])

添加主刻度/副刻度的网格线,which控制, alpha控制透明度

ax[i].grid(which=‘major’, color=‘gray’, linestyle=‘-’, linewidth=0.5, alpha=0.5)

设置x轴和y轴的范围

ax[i].axis([0, 3, 0, 10])

添加legend,也就是显示每条不同的线代表什么的小表格

ax[i].legend()

注意这里是画布或者画板调用show,而绘图区/坐标轴是无法调用show的

plt.show()

“”“## 2.6 散点图代码及使用示例”“”

Example 1

x, y = [i for i in range(10)], [i for i in range(10)]

plt.figure(figsize=(10, 6), dpi=80)

plt.scatter(x, y)

plt.show()

“”"

2.7 柱状图的代码及使用示例"“”

Example 1

categories = [‘Category A’, ‘Category B’, ‘Category C’, ‘Category D’]
values = [23, 45, 56, 78]

创建柱状图

fig, ax = plt.subplots(layout=‘constrained’)

绘制柱状图

‘align’ 控制柱体与标签的对齐方式,‘edge’ 表示柱体边缘对齐到刻度标签位置

‘color’ 可以设置柱体颜色,plt.cm.tab20.colors调用系统设置好的20种容易区分的颜色

‘edgecolor’ 设置柱体边缘颜色

ax.bar(categories, values, align=‘center’, color=‘skyblue’, edgecolor=‘black’)

ax.bar(categories, values, align=‘center’, color=plt.cm.tab20.colors, edgecolor=‘black’)

添加标题和轴标签

ax.set_title(‘Values per Category’)
ax.set_xlabel(‘Categories’)
ax.set_ylabel(‘Values’)

显示数值标签

for i, value in enumerate(values):
ax.text(i, value+1, str(value), ha=‘center’)

显示网格线

ax.grid(True, axis=‘y’, linestyle=‘–’, alpha=0.7)

plt.show()

Example 2

categories = [‘Stud A’, ‘Stud B’, ‘Stud C’, ‘Stud D’]
values1 = [23, 45, 56, 78]
values2 = [36, 28, 39, 17]

fig, ax = plt.subplots(layout=‘constrained’)
width = 0.6
offset = [i for i in range(0,8,2)]

绘制柱状图时,使用偏移的位置

ax.bar(offset, values1, align=‘center’, color=“skyblue”, edgecolor=‘black’, width=width, label=‘First Exam’)
ax.bar([i+width for i in offset], values2, align=‘center’, color=“orange”, edgecolor=‘black’, width=width, label=‘Second Exam’)

设置X轴刻度标签

ax.set_xticks([i + width/2 for i in offset]) # 使用两个柱的中点位置来对齐文本
ax.set_xticklabels(categories) # 设置类别名称为X轴标签

调整文本标签的位置

for i in range(len(values1)):
ax.text(i2, values1[i]+1, str(values1[i]), ha=‘center’) # 为第一组数据设置文本标签
ax.text(i
2+width, values2[i]+1, str(values2[i]), ha=‘center’) # 为第二组数据设置文本标签

ax.set_title(‘First and Second Exam score’)
ax.set_xlabel(‘Score’)
ax.set_ylabel(‘Values’)

ax.grid(True, axis=‘y’, linestyle=‘–’, alpha=0.7)

添加图例

ax.legend()

plt.show()

“”"## 2.8 直方图的代码以及使用示例

  • 组数:在统计数据时,把数据按照不同的范围分成的几个组,组的个数。
  • 组距:每组的两个端点的差值。
    “”"

import random
import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl

Example 1

fig, ax = plt.subplots(layout=‘constrained’, figsize=(10, 6))
data = [random.randint(50, 250) for i in range(30)] # 生成30个50-250之间的随机数据

绘制直方图

bins参数定义柱体的数量(组数),可以是一个整数或一个序列定义边界

alpha参数定义透明度,edgecolor定义柱体边缘的颜色

ax.hist(data, bins=(max(data)-min(data))//10, alpha=0.7, color=‘blue’, edgecolor=‘black’)

添加标题和轴标签

ax.set_title(‘Histogram of Random Numbers’)
ax.set_xlabel(‘Value Range’)
ax.set_ylabel(‘Frequency’)

添加网格线

ax.grid(True, which=‘both’, axis=‘both’, linestyle=‘–’, alpha=0.5)

显示图表

plt.show()

“”“## 2.9 饼图的代码以及使用示例”“”

import matplotlib.pyplot as plt

Example 1

range_name = [“NA”, “A”, “M”, “E”]
data = [0.2, 0.3, 0.4, 0.1]

创建饼图

fig, ax = plt.subplots(layout=‘constrained’, figsize=(10, 6))

绘制饼图

‘autopct’ 用于格式化百分比标签,‘explode’ 用于突出显示某一块

colors=plt.cm.tab20.colors 从colormap中调取用于类别图的颜色。

explode = (0, 0.1, 0, 0) # 例如,这里突出显示第二块
ax.pie(data, explode=explode, labels=range_name, autopct=‘%.2f%%’, startangle=90, colors=plt.cm.tab20.colors)

添加图例

ax.legend(title=“Categories”)

添加标题

ax.set_title(‘Distribution of Categories’)

显示图表

plt.show()

“”"# 3.Numpy运算库

3.1 什么是Numpy,为什么学习

  • NumPy(Numerical Python的简写)是一个开源的Python库,用于支持大量的维度数组与矩阵运算,此外也针对数组运算提供了大量的数学函数库。NumPy是科学计算中一个非常重要的包,广泛应用于加载、存储和处理大型数组的快速高效处理。
  1. 性能:NumPy的核心是在C语言和Fortran语言编写的,这使得NumPy的运算速度比纯Python快得多。
  2. 多维数组支持:NumPy支持多维数组(ndarray),这是进行科学计算的基础。
  3. 广泛的数学函数库:NumPy提供了大量的数学函数,可以轻松地进行各种数学计算,包括线性代数、统计操作等。
  4. 集成:NumPy可以与各种数据分析、机器学习库无缝集成,如Pandas、SciPy、Matplotlib、scikit-learn等。
  5. 内存效率:NumPy的数组存储在连续的内存块中,由于较少的内存占用和快速的处理,可以处理大量数据。

3.2 numpy中的ndarray

  • numpy提供的N维数组类型,描述了相同类型的items的集合,这就是ndarray

1.简单使用

“”"

import random
import numpy as np

score = np.array([
[random.randint(50,100) for i in range(5)] for i in range(5)
])

score

type(score)

“”"## 3.3 原生list和ndarray运算时间对比

  • ndarray仅能存储单一类型的数据格式
  • ndarray支持并行化运算
  • ndarray底层语言为c,解除了GIL(全局解释器锁),不受python解释器的限制
    “”"

import numpy as np
import time

创建大型列表和NumPy数组

list_size = 10000000
python_list = list(range(list_size))
numpy_array = np.array(python_list)

测量对列表的运算时间

start_time_list = time.time()
list_result = [x * 2 for x in python_list]
end_time_list = time.time()
time_for_list = end_time_list - start_time_list

测量对NumPy数组的运算时间

start_time_array = time.time()
array_result = numpy_array * 2
end_time_array = time.time()
time_for_array = end_time_array - start_time_array

print(f"list: {time_for_list}\nndarray: {time_for_array}")

“”“## 3.4 ndarray的属性”“”

import numpy as np
import random

score = np.array([
[random.randint(50,100) for i in range(5)] for i in range(8)
])

print(f"shape: {score.shape}“) # 几行几列
print(f"dtype: {score.dtype}”) # 数据类型

“”"## 3.5 ndarray shape示例

  • [[1,2,3],[2,3,4]]
    • (2,3),第一层两个元素,第二层三个元素。
  • [1,2,3,4]
    • (4,),第一层四个元素。
  • [[[1,2,3],[2,3,4]],[[4,5,6],[6,7,8]]]
    • (2,2,3) …

3.6 ndarray生成数组方法

  • 1.生成01数组
  • 2.从现有数组中生成
  • 3.生成固定范围的数组
  • 4.生成随机数组
    “”"

import numpy as np

1.生成01数组

zero_list = np.zeros(shape=[3,3],dtype=“int32”)
one_list = np.ones(shape=[3,3])
print(zero_list, “\n\n”, one_list, “\n”)

2.从现有数组中生成

data1 = [[1,2,3],[2,3,4]]
copys = np.array(data1) # np.array是deep copy
print(copys, “\n”)

3.生成固定范围的数组

lines1 = np.linspace(0,10,5) # 生成0-10,左右闭口的,5个等距的数
lines2 = np.arange(0,10,5) # 和range效果一样
print(lines1, “\n\n”, lines2, “\n”)

4.生成随机数

random_list1 = np.random.uniform(low=-1,high=1,size=10000) # 生成均匀分布的随机数
random_list2 = np.random.normal(loc=1.75,scale=0.1,size=10000) # 生成正态分布的随机数,loc是均值,scale是差值

random_list2 = np.random.normal(0, 1, (10, 5)) 直接传递shape也可以

“”"### 3.6.1 正态分布的补充知识

1.正态分布定义

正态分布(高斯分布)是一种连续概率分布,其概率密度函数(PDF)的形式由两个参数决定:均值((\mu))和标准差((\sigma))。

2.概率密度函数

正态分布的概率密度函数为:

f ( x ∣ μ , σ ) = 1 σ 2 π e − ( x − μ ) 2 2 σ 2 f(x|\mu,\sigma) = \frac{1}{\sigma\sqrt{2\pi}} e^{-\frac{(x-\mu)^2}{2\sigma^2}} f(xμ,σ)=σ2π 1e2σ2(xμ)2

  • (x):随机变量的值
  • (\mu):分布的均值,决定了分布的中心位置
  • (\sigma):分布的标准差,描述了数据的分散程度
  • (\sigma^2):方差

3.参数解释及其影响

  • 均值 ((\mu)):指定了分布的中心。改变 (\mu) 会使分布沿 x 轴移动,但不会改变其形状。

  • 标准差 ((\sigma)):度量了分布中数值的离散程度。较小的 (\sigma) 会让分布更紧凑,峰值更高;较大的 (\sigma) 会使分布更宽散,峰值更低。

4.np.random.normal 的使用

np.random.normal 函数允许根据正态分布生成随机数,其基本语法如下:

numpy.random.normal(loc=0.0, scale=1.0, size=None)

参数说明:

  • loc:正态分布的均值 (\mu)
  • scale:正态分布的标准差 (\sigma)
  • size:生成的随机数的数量或形状shape

5.正态分布数据的生成过程

要从理论上生成一组遵循正态分布的数据,我们需要依据正态分布的概率密度函数(PDF)和其参数(均值 (\mu) 和标准差 (\sigma))。但在实际操作中,我们并不是直接使用正态分布的PDF公式来手动计算每个点的值。相反,我们通常依赖于随机数生成算法,如Box-Muller变换或Ziggurat算法,这些算法能高效地生成满足特定正态分布参数的随机数。

  1. 确定分布参数:首先,你需要确定正态分布的参数,即均值 (\mu) 和标准差 (\sigma)。这两个参数定义了你希望生成数据的分布特性。

  2. 使用随机数生成算法:实际上,生成正态分布数据的过程是通过随机数生成算法实现的,而不是直接从PDF公式计算。例如,NumPy库的np.random.normal函数内部使用这样的算法来生成数据。

  3. 生成随机样本:通过指定的算法,计算机会生成一组随机数,这些随机数在统计上遵循你所指定的正态分布(具有特定的 (\mu) 和 (\sigma))。

3.7 ndarray的重塑方法

1.reshape

reshape方法用于在不改变数组数据的前提下,改变数组的形状。

  • 语法numpy.reshape(a, newshape)

其中a是要被重塑的数组,newshape是整数或整数元组,指定了新的形状。新形状应该与原始形状兼容,即总元素数量保持不变。

  • 示例
import numpy as np

a = np.arange(6) # 创建一个数组[0, 1, 2, 3, 4, 5]
print(a.reshape(2, 3)) # 重塑为2行3列的数组

2.resize

resize方法与reshape类似,也用于改变数组的形状,但它可以修改原始数组,并且在需要时可以填充或截断原数组以匹配新形状。

  • 语法numpy.resize(a, new_shape)

这里,a是要调整大小的数组,而new_shape是新的形状。如果新形状的总元素多于原始数组,resize会重复数组中的元素来填充新数组。

  • 示例
import numpy as np

a = np.array([1, 2, 3, 4])
b = np.resize(a, (2, 3))
print(b)

3.T方法

T属性是数组的转置视图,它将数组的行和列互换。

  • 使用:对于二维数组,T简单地交换其维度。对于多于两维的数组,T属性返回数组的简单转置,这等同于反转其轴的顺序。

  • 示例

import numpy as np

a = np.array([[1, 2], [3, 4], [5, 6]])
print(a.T)  # 转置数组

3.8 ndarray的类型转换方法

1.astype方法

astype方法用于将ndarray数组中的元素从一种类型转换成另一种类型。这是通过创建原数组的一个新副本来实现的,副本中的数据类型被转换为指定的类型。

  • 语法ndarray.astype(dtype, order='K', casting='unsafe', subok=True, copy=True)

  • 参数

    • dtype:新的数据类型。可以是NumPy数据类型对象或表示数据类型的字符串。
    • 其他参数控制着转换的具体行为,但通常dtype是最常用的参数。
  • 示例

import numpy as np

arr = np.array([1, 2, 3, 4])
float_arr = arr.astype(np.float64)
print(float_arr)  # 输出转换类型后的数组

这个示例中,整数数组被转换成了浮点数数组。

2.tobytes方法

tobytes方法将数组的元素转换为其二进制表示形式的字符串。这在进行低级别的二进制数据操作或将数组数据保存到文件中为二进制格式时特别有用。

  • 语法ndarray.tobytes(order='C')

  • 参数

    • order:指定元素在二进制字符串中的顺序。默认为’C’,即按行主顺序排列。'F’表示按列主顺序排列。
  • 示例

import numpy as np

arr = np.array([1, 2, 3, 4], dtype=np.int32)
binary_data = arr.tobytes()
print(binary_data)  # 输出二进制字符串

3.frombuffer方法

为了从二进制数据中恢复出ndarray对象

  • 语法numpy.frombuffer(buffer, dtype=float, count=-1, offset=0)

  • 参数

    • buffer:包含原始数据的缓冲区。
    • dtype:数组的数据类型。
    • 其他参数控制着数组的形状和解释缓冲区的方式。
  • 示例

import numpy as np

binary_data = b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00'
arr = np.frombuffer(binary_data, dtype=np.int32)
print(arr)

3.9 ndarray数组去重

1.数组去重

NumPy中去重数组的主要函数是np.unique。这个函数不仅可以找出数组中所有唯一元素,并且按照从小到大的顺序返回这些唯一元素。

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

  • 参数

    • arr:输入数组。
    • return_index:如果为True,则返回唯一元素的原始数组中的索引。
    • return_inverse:如果为True,则返回一个数组,用于重建原始数组。
    • return_counts:如果为True,则返回每个唯一元素在原数组中出现的次数。
    • axis:沿着它去重数组,默认为None,即将数组展平后去重。
  • 示例

import numpy as np

arr = np.array([1, 2, 2],[3, 3, 4])
unique_arr = np.unique(arr)
print(unique_arr)  # 输出:[1 2 3 4]

2.用途

  • 数据清洗:在分析数据之前,去除重复的观察值,确保分析的准确性。
  • 特征工程:在机器学习中,去重可以帮助识别和生成更有效的特征。
  • 统计分析:计算唯一事件的发生次数,或者分析不同类别的数量。
  • 内存优化:在处理大规模数据集时,去重可以减少内存的使用。

3.10 ndarray的逻辑运算

1.布尔索引

  • 布尔索引允许你使用布尔数组来选择数组中的元素。当你在索引操作中使用布尔数组时,结果数组将只包含对应于布尔数组中True值位置的元素。
import numpy as np

a = np.array([1, 2, 3, 4, 5])
bool_index = a > 2  # 布尔索引
print(a[bool_index])  # 输出满足条件的元素

2.all 和 any 函数

  • all:检查数组中的所有元素是否都满足某个条件(即是否都为True)。如果是,则返回True;否则返回False
  • any:检查数组中是否至少有一个元素满足某个条件(即为True)。如果是,则返回True;否则返回False
b = np.array([1, 2, 3, 4, 5])
condition = b > 3
print(np.all(condition))  # 检查是否所有元素都为符合条件
print(np.any(condition))  # 检查是否至少有一个元素符合条件

3.where 函数

where函数是NumPy中的三元运算符,用于基于条件从两个数组中选择元素。它的基本用法是np.where(condition, x, y),其中condition是一个布尔数组,xy是可选的;当condition的某个位置为True时,where将从x中选择元素,否则从y中选择。

使用where
  • 基本用法
c = np.array([1, 2, 3, 4])
result = np.where(c > 2, c, c*10)
print(result)  # 条件为True时选择c,否则选择c*10
  • 结合逻辑运算(andor

在NumPy中进行逻辑运算时,应使用&(逻辑与)和|(逻辑或)代替andor,同时注意条件表达式需要用括号括起来。

# 使用and条件
result_and = np.where((c > 2) & (c < 4), c, -1)
print(result_and)  # 满足c>2且c<4时选择c,否则为-1

# 使用or条件
result_or = np.where((c <= 2) | (c == 4), c, -1)
print(result_or)  # 满足c<=2或c==4时选择c,否则为-1

3.11 ndarray统计函数

1.常用NumPy统计函数及其作用

  • np.meanarr.mean - 计算平均值
  • np.median - 计算中位数
    • 注意:median没有对应的数组方法,只能通过np.median(arr)调用
  • np.stdarr.std - 计算标准差
  • np.vararr.var - 计算方差
  • np.sumarr.sum - 计算总和
  • np.minarr.min - 计算最小值
  • np.maxarr.max - 计算最大值
  • np.argminarr.argmin - 查找最小值的索引
  • np.argmaxarr.argmax - 查找最大值的索引
  • np.percentile - 计算百分位数
    • median类似,percentile也没有直接对应的数组方法

3.11.1 axis的使用

  • 大部分统计函数都可以传入axis参数。
  • 根据shape的下标调用即可。
    • [[1,2,3,4],[2,3,4,5],[3,4,5,6]] 的shape=(3,4)
    • 从代码角度来看,第一层有三个元素,第二层有四个元素。
    • 从实际意义角度来看,第一层是3个学生,第二层是4个科目。
    • 想要对哪个对象进行处理,直接找到shape中其下标位置即可。
      “”"

import numpy as np

创建一个二维数组,表示3个学生的4门科目成绩

grades = np.array([
[88, 92, 80, 89], # 学生1
[85, 87, 86, 85], # 学生2
[78, 81, 89, 88] # 学生3
])

计算每个学生的平均成绩,即沿着科目方向(axis=1)

student_means = grades.mean(axis=1)

计算每门科目的平均成绩,即沿着学生方向(axis=0)

subject_means = grades.mean(axis=0)

print(“每个学生的平均成绩:”, student_means)
print(“每门科目的平均成绩:”, subject_means)

“”"### 3.11.2 方差/标准差的补充知识

1.方差(Variance)

方差是衡量数据分布离散程度的指标,表示各数据点与平均值之差的平方的平均值。方差的数学公式为:

σ 2 = ∑ ( x i − μ ) 2 N \sigma^2 = \frac{\sum (x_i - \mu)^2}{N} σ2=N(xiμ)2

  • 其中, σ 2 \sigma^2 σ2 表示方差, x i x_i xi 表示每个数据点, μ \mu μ 表示数据的平均值, N N N 是数据点的总数。

方差越大,意味着数据点相对于平均值的分散程度越大。

2.标准差(Standard Deviation)

标准差是方差的平方根,它提供了与原始数据相同单位的离散程度度量。标准差的公式为:

σ = ∑ ( x i − μ ) 2 N \sigma = \sqrt{\frac{\sum (x_i - \mu)^2}{N}} σ=N(xiμ)2

  • 其中, σ \sigma σ 表示标准差,其他符号与方差公式中的相同。

标准差越大,表明数据分布越分散。

3.例子

考虑一个简单的例子:一个班级里5名学生的数学成绩分别为60, 70, 80, 90, 100。

首先,计算平均成绩( μ \mu μ):

μ = 60 + 70 + 80 + 90 + 100 5 = 80 \mu = \frac{60 + 70 + 80 + 90 + 100}{5} = 80 μ=560+70+80+90+100=80

接着,计算方差( σ 2 \sigma^2 σ2):

σ 2 = ( 60 − 80 ) 2 + ( 70 − 80 ) 2 + ( 80 − 80 ) 2 + ( 90 − 80 ) 2 + ( 100 − 80 ) 2 5 = 400 + 100 + 0 + 100 + 400 5 = 200 \sigma^2 = \frac{(60-80)^2 + (70-80)^2 + (80-80)^2 + (90-80)^2 + (100-80)^2}{5} = \frac{400 + 100 + 0 + 100 + 400}{5} = 200 σ2=5(6080)2+(7080)2+(8080)2+(9080)2+(10080)2=5400+100+0+100+400=200

最后,计算标准差( σ \sigma σ):

σ = 200 ≈ 14.14 \sigma = \sqrt{200} \approx 14.14 σ=200 14.14

这表明,尽管学生的平均成绩为80分,但他们的成绩围绕平均值上下波动大约14分,这提供了成绩分布离散程度的一个度量。

3.12 ndarray数组间运算

在NumPy中,数组间的运算和广播机制是处理多维数据时的核心概念,它们允许进行高效的矢量化计算,避免了显式的循环。这些特性使得NumPy在科学计算中非常强大。

1.数组间运算

  • NumPy支持数组间的元素级运算,包括加、减、乘、除等基本运算,这些运算是逐元素进行的。

    import numpy as np
    
    a = np.array([1, 2, 3])
    b = np.array([4, 5, 6])
    
    # 元素级加法
    c = a + b
    # 元素级乘法
    d = a * b
    
    print(f"a + b = {c}")
    print(f"a * b = {d}")
    
    • 这里,a + ba * b都是逐元素进行的操作,结果分别是两个数组对应元素的和与乘积。

2.广播机制

  • 广播机制允许NumPy在执行数组运算时自动扩展数组的形状,使得具有不同形状的数组能够进行运算。为了满足广播规则,NumPy执行以下步骤:

    1. 如果两个数组维度数不同,将维度数较小的数组形状前面填充1,直到两个数组的维度数相同。
    2. 检查两个数组在每个维度上的大小,它们要么相同,要么其中一个为1。如果条件不成立,则无法广播。
    3. 对于维度大小为1的任意维度,该维度在运算中的大小会扩展到与另一个数组在该维度的大小相同。
    import numpy as np
    
    a = np.array([1, 2, 3])
    b = np.array([[1], [2], [3]])
    
    # 通过广播,a的形状被扩展为(3, 3),b的形状也被扩展为(3, 3),然后进行逐元素相加
    c = a + b
    
    print(f"a + b = \n{c}")
    
  • 在这个例子中,a的形状为(3,),而b的形状为(3, 1)。根据广播规则,a的形状被扩展为(3, 3)b的形状也被扩展为(3, 3),然后两个数组可以进行逐元素相加。

3.12.1 广播机制的补充知识

以刚才的例子为基础,来详细讲解如何通过广播机制进行运算。

给定两个数组:

a = np.array([1, 2, 3])
b = np.array([[1], [2], [3]])
  • 这里,a的形状为(3,),意味着它是一个一维数组,包含3个元素。b的形状为(3, 1),意味着它是一个二维数组,有3行1列。

  • 当执行a + b时,NumPy会自动应用广播机制,步骤如下:

    1. 形状对齐:首先,比较两个数组的维度,将较小维度的数组形状在前面填充1,使得两个数组的维度数相同。在本例中,数组a的形状会从(3,)扩展为(1, 3),以匹配b的二维形状。此时,ab的形状分别变为:
    • a(1, 3)
    • b(3, 1)
    1. 广播:接下来,NumPy检查每个维度,确保它们是兼容的,即每个维度的大小要么相同,要么其中一个为1。在本例中:
    • 第一个维度中,a为1,b为3。由于a在该维度上的大小为1,它可以被扩展以匹配b的大小。
    • 第二个维度中,a为3,b为1。同样,b在该维度上的大小为1,它可以被扩展以匹配a的大小。

    通过广播,a被扩展为一个(3, 3)的二维数组,b也被扩展为一个(3, 3)的二维数组,具体如下:

    a扩展后: [[1, 2, 3],
           [1, 2, 3],
           [1, 2, 3]]
    
    b扩展后: [[1, 1, 1],
           [2, 2, 2],
           [3, 3, 3]]
    
    1. 逐元素相加:现在,ab都被扩展为同样的形状,它们可以进行逐元素的相加操作:
    [[1+1, 2+1, 3+1],
     [1+2, 2+2, 3+2],
     [1+3, 2+3, 3+3]]
    
    结果为: [[2, 3, 4],
           [3, 4, 5],
           [4, 5, 6]]
    

3.13 ndarray的矩阵运算

1.矩阵加法和减法

  • 矩阵的加法和减法是逐元素进行的。两个形状相同的矩阵可以直接相加或相减。

    import numpy as np
    
    # 创建两个2x2矩阵
    A = np.array([[1, 2], [3, 4]])
    B = np.array([[5, 6], [7, 8]])
    
    # 矩阵加法
    C = A + B
    # 矩阵减法
    D = A - B
    
    print(f"A + B =\n{C}")
    print(f"A - B =\n{D}")
    

2.点乘(元素乘)

  • 点乘指的是两个矩阵相同位置的元素相乘,结果是一个同样形状的新矩阵。

    # 元素乘
    E = A * B
    
    print(f"A * B (element-wise) =\n{E}")
    

3.矩阵乘法

  • 矩阵乘法(又称为点积、内积)不同于元素乘,它按照线性代数中的规则进行计算。

    # 矩阵乘法
    F = np.dot(A, B)  # 或者使用 A @ B
    
    print(f"A dot B =\n{F}")
    

4.矩阵转置

  • 和ndarray相同,使用.T方法即可。

矩阵的逆

  • 矩阵的逆是指一个矩阵乘以其逆矩阵的结果为单位矩阵。

    # 矩阵逆
    H = np.linalg.inv(A)
    
    print(f"Inverse of A =\n{H}")
    

3.13.1 矩阵乘法的补充知识

  • 这种乘法不同于元素级乘法,它遵循线性代数中的矩阵乘法规则,即第一个矩阵的列数必须与第二个矩阵的行数相等。

1.矩阵乘法的计算

  • 给定两个矩阵 (A) 和 (B),其中 (A) 是一个 (m * n) 矩阵,(B) 是一个 (n * p) 矩阵,它们的乘积 (C = AB) 是一个 (m * p) 矩阵,其中 (C) 的每个元素是通过下面的方式计算得到的:

  • $ C_{ij} = \sum_{k=1}^{n} A_{ik}B_{kj} $

  • 这意味着结果矩阵的第 (i) 行第 (j) 列的元素是由第一个矩阵的第 (i) 行与第二个矩阵的第 (j) 列进行点乘得到的。

2.示例

假设有两个矩阵 (A) 和 (B):

  • (A) 是一个 (2 * 3) 矩阵:

  • A = \begin{pmatrix} 1 & 2 & 3 \ 4 & 5 & 6 \end{pmatrix}

  • (B) 是一个 (3 * 2) 矩阵:

  • B = \begin{pmatrix} 7 & 8 \ 9 & 10 \ 11 & 12 \end{pmatrix}

  • 计算 (A) 和 (B) 的乘积:

    import numpy as np
    
    A = np.array([
      [1, 2, 3],
      [4, 5, 6]
    ])
    
    B = np.array([
      [7, 8],
      [9, 10],
      [11, 12]
    ])
    
    C = np.dot(A, B)  # 或者 C = A @ B
    print(C)
    
  • 执行这段代码后,将得到矩阵 (C):

  • C = \begin{pmatrix} 58 & 64 \ 139 & 154 \end{pmatrix}

其中,

  • (C_11 = (1 * 7) + (2 * 9) + (3 * 11) = 58)
  • (C_12 = (1 * 8) + (2 * 10) + (3 * 12) = 64)
  • (C_21 = (4 * 7) + (5 * 9) + (6 * 11) = 139)
  • (C_22 = (4 * 8) + (5 * 10) + (6 * 12) = 154)
    “”"

Example 矩阵乘法的使用

给出n个学生的平时成绩和期末成绩,根据占比,来求出该学生的最终成绩

例:平时分94,期末分89,平时占比30%,期末占比70%,94 * 0.3 + 89 * 0.7

import numpy as np

data1 = np.array([ # shape 42
[70, 83],
[68, 71],
[83, 65],
[32, 96]
])
data2 = np.array([ # shape 2
1
[0.3],
[0.7]
])

res = np.dot(data1, data2)

res # shape 4*1

“”"## 3.14 ndarray合并与分割

1.ndarray合并

NumPy中常用的数组合并函数包括:

  • np.concatenate:沿指定轴连接数组序列。
  • np.vstack(垂直栈):沿着垂直轴堆叠数组。
  • np.hstack(水平栈):沿着水平轴堆叠数组。
import numpy as np

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

# 水平合并
c = np.hstack((a, b))  
# array([1, 2, 3, 4, 5, 6])

# 垂直合并
d = np.vstack((a, b))  
# array([[1, 2, 3],
#    [4, 5, 6]])

2.ndarray分割

相对应的,NumPy也提供了函数来分割数组:

  • np.split:将数组分成多个子数组。
  • np.hsplit:沿水平轴分割数组。
  • np.vsplit:沿垂直轴分割数组。
# 创建一个数组
arr = np.arange(9).reshape(3,3)
# 水平分割
result = np.hsplit(arr, 3)
# 垂直分割
result2 = np.vsplit(arr, 3)

注意事项

  • 合并时,除了要合并的轴外,其他轴的大小必须相同。
  • 分割时,指定的分割数量或分割位置必须能够被数组在指定轴上的大小整除。

3.15 Numpy的IO交互,读取文件

1. 使用numpy.loadtxt()读取文本文件:

import numpy as np

data = np.loadtxt('data.txt', delimiter=',')

这里,'data.txt'是要读取的文件名,delimiter=','指定了数据之间的分隔符为逗号。loadtxt()函数会将文件中的数据读取到一个NumPy数组中。

2. 使用numpy.genfromtxt()读取文本文件:

import numpy as np

data = np.genfromtxt('data.csv', delimiter=',')

genfromtxt()函数类似于loadtxt(),但它更加灵活,可以处理缺失值和不同的数据类型。它也支持使用delimiter参数指定分隔符。

3. 使用numpy.fromfile()读取二进制文件:

import numpy as np

data = np.fromfile('data.bin', dtype=np.float64)

fromfile()函数用于读取二进制文件。你需要指定数据的类型,例如dtype=np.float64表示读取双精度浮点数。

4. 使用numpy.load()读取NumPy的.npy.npz文件:

import numpy as np

data = np.load('data.npy')

3.16 读取后,处理Nan值

1.删除含有缺失值的样本

  • 如果有大量数据,可以这样操作。

2.替换、插补

  • 按列求平均,用平均值进行填补。
  • 例:行是一只股票在一段时间内的涨跌数据,那么列就是所有股票在同一天的涨跌数据,那么,想要弥补空缺值Nan,只要填补该天所有不为Nan的股票数据的平均值即可,不会影响总体的计算。
  • numpy没有直接能够替换插补的方法,所以一般使用pandas来进行这一步。

4.Pandas数据处理库

4.1 什么是Pandas,为什么使用

  • 介绍

    • 2008年由WesMcKinney开发的库
    • 专用于数据挖掘的开源py库
    • 集成numpy
    • 集成matplotlib
    • 独特的数据结构,可以清晰的表示数据是什么
  • 为什么使用pandas

    • 便捷的数据处理能力,如替换Nan值
    • 读取文件方便
    • 集成了Numpy和Matplotlib的计算和画图

4.2 pandas的独特数据结构

Pandas是一个开源数据分析和处理的Python库,它提供了高性能、易用的数据结构和数据分析工具。DataFrame是Pandas中最常用的数据结构之一,用于处理结构化数据,类似于Excel中的表格或SQL数据库中的表。

4.2.1 DataFrame

  • 定义:DataFrame是一个二维的、大小可变的、异质性数据表格,有行标签和列标签。
  • 特点:可以存储多种类型的数据,如整数、浮点数、字符串、Python对象等。
  • 用途:适用于各种数据操作,包括数据清洗、转换、分析等。
  • 其本质是在ndarray外套了一层行列索引

1.创建DataFrame

可以通过多种方式创建DataFrame,包括字典、列表、外部数据文件等。

import pandas as pd

# 通过字典创建DataFrame
data = {
    'Name': ['John', 'Anna', 'Peter', 'Linda'],
    'Age': [28, 34, 29, 32],
    'City': ['New York', 'Paris', 'Berlin', 'London'],
    "date": pd.date_range(start='2024-3-1', periods=3, freq='D')
}
df = pd.DataFrame(data)
print(df)

2.DataFrame的属性

DataFrame有很多属性,可以用来访问关于DataFrame的信息。

  • .shape:返回DataFrame的行数和列数。
  • .dtypes:返回每列的数据类型。
  • .columns:返回列名。
  • .index:返回索引。
  • .values:返回DataFrame的数据部分,不包括行列标签,作为NumPy数组。

3.DataFrame的常用方法

  • .head().tail():分别查看DataFrame的前几行和后几行数据。
  • .describe():对DataFrame中的数值列进行描述性统计。
  • .sort_values(by='column_name'):按某列的值排序数据。
  • .groupby('column_name'):按某列的值分组数据。
print(df.head(2))  # 查看前2行
print(df.describe())  # 数值列的统计信息

4.对行列的常用操作

  • 选择:使用.loc[].iloc[]或列名选择数据。
  • 添加:可以直接赋值来添加新的列。
  • 删除:使用.drop()方法删除行或列。
  • 修改:直接通过索引或.loc[].iloc[]赋值修改。
  • 设置索引:使用.set_index('column_name')设置某列为索引。
# 选择
print(df['Age'])  # 选择一列
print(df.loc[0])  # 选择一行

# 添加
df['Country'] = ['USA', 'France', 'Germany', 'UK']

# 删除
df.drop('Country', axis=1, inplace=True)  # 删除列

# 修改
df.loc[0, 'Age'] = 30  # 修改某个值

# 设置索引
df.set_index('Name', inplace=True)

# 也可以使用set_index来实现MultiIndex
df.set_index(['Country', 'Name'], inplace=True)

“”"

import numpy as np
import pandas as pd
import random

Example 1

创建一个由numpy转换的股票案例

data1 = np.random.normal(0, 1, (10, 5))
pd.DataFrame(data1, index=[f"S{i}" for i in range(1, 11)], columns=pd.date_range(start=‘2024-3-1’, periods=5, freq=‘D’))

Example 2

设置新索引

data1 = pd.DataFrame(
{
“Stock Name”: [“A”, “B”, “C”],
“Start Year”: [“2019”, “2021”, “2020”],
“Year1”: [random.uniform(-30, 30) for i in range(3)],
“Year2”: [random.uniform(-30, 30) for i in range(3)],
“Year3”: [random.uniform(-30, 30) for i in range(3)],
}
)

将单个/多个已存在的列设为索引

data1.set_index(“Stock Name”)
data1.set_index([“Stock Name”,“Start Year”], inplace=True) # inplace代表是否保留不为索引的内容,True为不保留
data1

“”"### 4.2.2 MultiIndex

1.MultiIndex

MultiIndex是Pandas中的一种数据结构,用于表示多级(或层次化)索引。这种索引结构允许你在一个轴上(无论是行还是列)有多个(两个以上)索引级别,从而使你能够以更高维度组织和操作数据。使用MultiIndex可以让你在DataFrame中处理更复杂的数据形式,比如分组、分类和其他形式的层次化数据。

“”"

import pandas as pd
import numpy as np

Example 1

创建一个多级索引(MultiIndex)

index = pd.MultiIndex.from_tuples([(‘A’, ‘2024’), (‘A’, ‘2025’), (‘B’, ‘2024’), (‘B’, ‘2025’)], names=[‘Stock’, ‘Year’])
columns = [‘Jan’, ‘Feb’, ‘Mar’]

使用MultiIndex创建DataFrame

data = np.random.rand(4,3) # 随机数据
pd.DataFrame(data, index=index, columns=columns)

Example 2

由于Panel已被弃用,下面展示如何使用具有MultiIndex的DataFrame来处理相同的三维数据:

假设我们有三维数据:年份、股票代码和月份

years = [‘2024’, ‘2025’]
stocks = [‘A’, ‘B’]
months = [‘Jan’, ‘Feb’, ‘Mar’]

创建一个三维的MultiIndex

multi_index = pd.MultiIndex.from_product([years, stocks, months], names=[‘Year’, ‘Stock’, ‘Month’])

使用MultiIndex创建DataFrame

res = pd.DataFrame(np.random.rand(len(multi_index)), index=multi_index, columns=[‘Value’])

res

抓取数据

1.访问抓取.loc方法

res.loc[“2024”, “A”, “Jan”]

2.跨级别抓取.xs方法

res.xs(“A”, level=“Stock”)

“”"### 4.2.3 Series

Series是Pandas库中的一种基本数据结构,它用于存储一维的标签化数组。Series对象可以看作是一个带有索引的一维数组。

与NumPy的数组不同,Series可以有一个自定义的索引标签,意味着你可以使用索引标签来访问数据,而不仅仅是数字位置。

独特属性

  • .indexSeries的索引标签。
  • .valuesSeries数据的数组表示。
  • .dtype:数据的类型。
  • .nameSeries的名称,可以在创建时指定,也可以之后设置。

独特方法

  • .describe():提供Series数据的描述性统计。
  • .apply():对Series中的每个元素应用指定的函数。
  • .value_counts():计算Series中各值出现的频次。
  • .sort_values().sort_index():分别按值和按索引对Series进行排序。
    “”"

import pandas as pd

data = pd.Series([1, 3, 5, 7, 9], index=[‘a’, ‘b’, ‘c’, ‘d’, ‘e’])

通过索引标签访问

print(data[‘b’])

通过位置访问

print(data[1])

描述性统计

print(data.describe())

应用函数

print(data.apply(lambda x: x**2))

值的频次

print(data.value_counts())

排序

print(data.sort_values(ascending=False))

“”"## 4.3 DataFrame的基本数据操作,及四种行列索引。

“”"

import numpy as np
import pandas as pd
import random as rd

读取csv文件

data = pd.read_csv(“File_Position”)

data = {
‘open’: [round(np.random.uniform(-50, 50), 2) for i in range(5)],
‘close’: [round(np.random.uniform(-50, 50), 2) for i in range(5)],
‘volume’: [round(np.random.uniform(20_000, 50000), 2) for i in range(5)],
‘ma5’: [round(np.random.uniform(-20, 20), 2) for i in range(5)],
‘ma10’: [round(np.random.uniform(-20, 20), 2) for i in range(5)],
}
row_index = pd.date_range(start=‘2024-3-1’, periods=5, freq=‘D’)
df = pd.DataFrame(data, index=row_index)

df

去除不想显示的列

df = df.drop([“ma5”], axis=1) # axis=0为行,1为列

1.直接索引, 通过列

print(df[“open”])

print(df[“open”][“2024-03-01”])

2.按名字索引,通过行

print(df.loc[“2024-03-01”])

print(df.loc[“2024-03-01”][“open”])

3.按数字索引, [行,列]

print(df.iloc[1])

print(df.iloc[1, 0])

4.混合索引

print(df.loc[df.index[:3], [“open”, “close”]])

print(df.iloc[:3, :2])

print(df.iloc[:3, [0,1]]) # 可以传入一个list的下标

1.修改行列信息,用四种索引方式都可以。

df[“open”] = 200 # 全覆盖为200

df.iloc[1] = [i for i in range(5)]

2.排序,根据列

df.sort_values([“open”, “close”], ascending=False) # 按照open列的值从小到大排序,如果open值相同,按close值再排序。

3.按日期排序, Series也是同样的函数来排序index。

df.sort_index()

“”"## 4.4 DataFrame的算数运算

“”"

使用4.3的数据

算数运算可以通过广播机制直接作用在所有值上,也可以通过行列索引作用于任何行列上,索引方式参考4种。

1.加10

df_add = df.add(10)

2.减10

print(df, “\n”)
df_sub = df[“open”].sub(10)
print(df_sub)

3.乘以2

df_mul = df.mul(2)

4.除以2

df_div = df.div(2)

5.模3

df_mod = df.mod(3)

6.乘方2

df_pow = df.pow(2)

“”"## 4.5 DataFrame的逻辑运算

  • 列与列,行与行,列/行与数值,之间的比较,返回的是bool的Series
    “”"

使用4.3的数据

1.检查 ‘open’ 列的值是否 大于 ‘close’ 列的值

greater_than = df[‘open’] > df[‘close’]

2.检查 ‘volume’ 列的值是否 小于 50000

volume_high = df[‘volume’] < 50000

3.同时满足 (‘open’ 大于 ‘close’) 且 (‘volume’ 小于 50000)

both_conditions = greater_than & volume_high

4.满足 (‘open’ 大于 ‘close’) 或 (‘volume’ 小于 50000)

either_condition = greater_than | volume_high

将得到的bool-series应用在原数据上, 进行类似数据库查找的操作

5.找到所有open大于0的行数据

find_greater_than_zero = df[df[“open”]>0]

6.找到所有open大于0,且close大于2的行数据

find_greater_zero_and_two = df[(df[“open”]>0) & (df[“close”]>2)]

逻辑函数方法的使用

7.更直接的查询

df.query(“open > 0 & close > 0”)

8.判断是否存在某数值

df[“open”].isin([19.2, 11.5])

“”“## 4.6 DataFrame的统计运算”“”

使用4.3的数据

计算最小值

min_values = df.min()

计算最大值

max_values = df.max()

计算平均值

mean_values = df.mean()

计算中位数

median_values = df.median()

计算标准差

std_dev = df.std()

计算求和

sum_values = df.sum()

计算方差

variance = df.var()

查找最小值的索引,返回的是所有列的最小值索引

idx_min = df.idxmin()

查找最大值的索引

idx_max = df.idxmax()

累计求和, 累计意味着从1-n天的所有和,例如用于查看一只股票开盘以来的总涨跌情况,返回一个f=[n]+[n-1]的series

cum_sum = df.cumsum()

累计最大值

cum_max = df.cummax()

累计最小值

cum_min = df.cummin()

累计乘积

cum_prod = df.cumprod()

自定义运算,使用apply函数即可, 传入自定函数,以及axis=0按列计算

例,计算每列的最大值和最小值的差

应用lambda

result = df.apply(lambda x: x.max()-x.min(), axis=0)

应用正常的函数,自动传参

def range_diff(x):
return x.max() - x.min()
result = df.apply(range_diff, axis=0)
result

“”“## 4.7 DataFrame的画图”“”

使用4.3的数据

import matplotlib.pyplot as plt

categories = df.index.date
values1 = df[“open”]
values2 = df[“close”]
frist_label = “open”
second_label = “close”
title = “stock open and close report”
x_label = “Stocks”
y_label = “Value”

fig, ax = plt.subplots(layout=‘constrained’)
width = 0.6
offset = [i for i in range(0,10,2)]

绘制柱状图时,使用偏移的位置

ax.bar(offset, values1, align=‘center’, color=“skyblue”, edgecolor=‘black’, width=width, label=frist_label)
ax.bar([i+width for i in offset], values2, align=‘center’, color=“orange”, edgecolor=‘black’, width=width, label=second_label)

设置X轴刻度标签

ax.set_xticks([i + width/2 for i in offset]) # 使用两个柱的中点位置来对齐文本
ax.set_xticklabels(categories) # 设置类别名称为X轴标签

调整文本标签的位置

for i in range(len(values1)):
ax.text(i2, values1[i]+1 if values1[i] > 0 else values1[i]-3, str(values1[i]), ha=‘center’) # 为第一组数据设置文本标签
ax.text(i
2+width, values2[i]+1 if values2[i] > 0 else values2[i]-3, str(values2[i]), ha=‘center’) # 为第二组数据设置文本标签

ax.set_title(title)
ax.set_xlabel(x_label)
ax.set_ylabel(y_label)

添加虚线

ax.grid(True, axis=‘y’, linestyle=‘–’, alpha=0.7)

添加图例

ax.legend()

plt.show()

“”“## 4.8 pandas-CSV”“”

import pandas as pd

1.读取

df = pd.read_csv(‘file.csv’)

参数:

指定列名

df = pd.read_csv(‘file.csv’, names=[‘col1’, ‘col2’, ‘col3’])

指定索引列

df = pd.read_csv(‘file.csv’, index_col=‘index_col_name’)

跳过指定行数的头部

df = pd.read_csv(‘file.csv’, skiprows=2)

指定缺失值标识符

df = pd.read_csv(‘file.csv’, na_values=[‘NA’, ‘N/A’])

2.写入

df.to_csv(‘output.csv’, index=False, mode=“w”)

参数:

指定列名

df.to_csv(‘output.csv’, columns=[‘col1’, ‘col2’])

写入不包括行索引

df.to_csv(‘output.csv’, index=False)

写入不包括列名

df.to_csv(‘output.csv’, header=False)

以制表符分隔

df.to_csv(‘output.csv’, sep=‘\t’)

“”"## 4.9 pandas-hdf5

  • hdf5的储存格式类似于key: dataframe
  • 因为dataframe是二维的,那么再加一维的hdf5可以看作是三维数组。
    “”"

1.写入

‘table’ 格式支持后续查询操作

df.to_hdf(‘data.h5’, key=‘df’, format=‘table’, mode=‘w’)

2.读取

df_read = pd.read_hdf(‘data.h5’, key=‘df’)

查询操作,只有当format为’table’时才能使用

df_query = pd.read_hdf(‘data.h5’, key=‘df’, where=[‘index>2’])

“”“## 4.10 pandas-Json”“”

1.写入

df.to_json(‘data.json’)

参数:

orient - 控制JSON格式,比如’split’,‘records’,‘index’,‘columns’,'values’等

force_ascii - 为了兼容性,默认为True,将所有非ASCII字符转义

date_format - 控制日期的格式化方式,默认为’epoch’

double_precision - 控制小数点后的精度,默认为10

ensure_ascii - 默认为True,所有非ASCII字符在输出时都会被转义

2.读取

df_read = pd.read_json(‘data.json’)

参数:

orient - 指定JSON字符串的格式

typ - 返回对象类型,默认为’frame’,表示返回DataFrame;'series’表示返回Series

convert_dates - 指定将JSON中的字段解析为日期,默认为True

convert_axes - 是否尝试将轴标签转换为适当的数据类型,默认为True

precise_float - 是否使用更精确的浮点转换,默认为False

“”"## 4.11 pandas处理缺失值Nan

  • 直接删除含有缺失值的样本 - 行
  • 根据其余样本数据填补平均值 - 列的平均值
    “”"

import pandas as pd
import numpy as np

1.创建一个包含缺失值的DataFrame

df = pd.DataFrame({
‘A’: [1, 2, np.nan, 4],
‘B’: [5, np.nan, np.nan, 8],
‘C’: [10, 11, 12, 13]
})

2.判断是否存在缺失值 isnull、notnull

missing_values = df.isnull().any()

两种方法

A.直接删除包含缺失值的样本(行)

df_dropped = df.dropna()

参数:

axis - 0 或 ‘index’ 删除包含缺失值的行, 1 或 ‘columns’ 删除包含缺失值的列

how - ‘any’ 删除任何有缺失值的行/列, ‘all’ 只删除全为缺失值的行/列

thresh - 设置行/列中非缺失值的最小数量,低于这个数量的行/列将被删除

inplace - 如果为True,则直接在原数据上修改,如果为False则返回一个新的DataFrame

B.填补缺失值:用各列的均值填补对应列的缺失值

df_filled = df.fillna(df.mean())

参数:

value - 可以是一个字典,指定每列填充的值

method - 'ffill’向前填充,'bfill’向后填充

axis - 0 或 ‘index’ 沿着行的方向填充, 1 或 ‘columns’ 沿着列的方向填充

inplace - 如果为True,则直接在原数据上修改,如果为False则返回一个新的DataFrame

3.处理其他类型的缺失值,如"?“,”"等,替换为Nan,之后就和处理Nan一样了

df_filled.replace(to_replace=“?”, value=np.nan)

“”"## 4.12 pandas处理数据离散化/one-hot编码

  • 离散化

    • 在机器学习中,将连续变量转换成有限数量的类别,简化模型的复杂性,提高对数据的泛化能力,尤其在处理非线性关系时更有效。
  • One-hot 编码

    • 用于将分类变量转换为二进制(0或1)格式,每个类别对应一个独立的特征,从而使得模型能够更好地处理无序(名义)类别数据,避免引入数值大小的误导。

pd.cut函数

  • bins 参数定义了将数据分割成不同区间的边界。
  • 这里我们使用 [0, 160, 180, float('inf')] 来定义三个区间:0到160cm,160到180cm,以及180cm以上。
  • 参数 right=False 指定区间的右边界是开区间。
  • labels参数用于为每个区间赋予一个标签。
  • 也可以使用qcut函数,pandas会自动分出区间,df.qcut(data, 区间数量)

pd.get_dummies函数

  • 用于创建独热编码的列,它会为 height_category 中的每个唯一标签添加一个新的列,如果该行的标签匹配,则在相应的列中使用1来表示,否则使用0。

“”"

import pandas as pd

df = pd.DataFrame(
{‘height’: [158, 165, 170, 174, 180, 185]}
)

定义区间边界和标签

bins = [0, 160, 180, float(‘inf’)] # float(‘inf’)代表无限
labels = [‘矮’, ‘中’, ‘高’]

使用 pd.cut 进行离散化

df[‘height_category’] = pd.cut(df[‘height’], bins=bins, labels=labels, right=False)

df[‘height_category’]

使用 pd.get_dummies 进行 One-Hot 编码, 这里返回的是一个新的dataframe

df_one_hot = pd.get_dummies(df, columns=[‘height_category’])
df_one_hot

value_count显示每组的数量

df[‘height_category’].value_counts()

“”"## 4.13 pandas组合方法 concat / merge

concat 函数

  • 用于沿着一条轴将多个 pandas 对象堆叠在一起。这可以用于简单地合并(堆叠)数据集,不涉及根据索引或列对数据进行对齐。

merge 函数

  • 用于根据一个或多个键将两个数据集的行连接起来。类似于 SQL 中的 JOIN 操作。
  • inner是合并都存在的索引。
  • outer是合并所有,不存在的索引内容会以Nan填充。
  • left和right就是根据哪个表的索引内容进行拼接。

“”"

import pandas as pd

1.pd.concat

df1 = pd.DataFrame({
‘Name’: [‘Alice’, ‘Bob’],
‘Age’: [25, 22]
})

df2 = pd.DataFrame({
‘Name’: [‘Cindy’, ‘Dan’],
‘Age’: [20, 23]
})
result = pd.concat([df1, df2], ignore_index=True, axis=0) # 0是垂直,1是水平
print(result)

2.pd.merge

df_a = pd.DataFrame({
‘Name’: [‘Alice’, ‘Bob’],
‘Age’: [25, 22]
})

df_b = pd.DataFrame({
‘Name’: [‘Alice’, ‘Bob’],
‘Score’: [88, 92]
})
result = pd.merge(df_a, df_b, on=[‘Name’]) # left,right,how=“inner”,on=索引
print(result)

“”"## 4.14 pandas的交叉表

  • 交叉表(crosstab),可以有效地对比两个类别变量的频率分布。
  • 假设想分析股票涨跌与星期几之间的关系

“”"

import pandas as pd
import numpy as np

设置随机种子,以便重现示例

np.random.seed(0)

模拟数据

df = pd.DataFrame({
‘DayOfWeek’: np.random.choice([‘Monday’, ‘Tuesday’, ‘Wednesday’, ‘Thursday’, ‘Friday’], size=100),
‘StockChange’: np.random.choice([‘Up’, ‘Down’], size=100)
})

将 ‘DayOfWeek’ 转换为有序类别类型

weekdays = [‘Monday’, ‘Tuesday’, ‘Wednesday’, ‘Thursday’, ‘Friday’]
df[‘DayOfWeek’] = pd.Categorical(df[‘DayOfWeek’], categories=weekdays, ordered=True)

cross_tab = pd.crosstab(df[‘DayOfWeek’], df[‘StockChange’])

print(cross_tab)

import matplotlib.pyplot as plt

绘制交叉表的条形图

cross_tab.plot(kind=‘bar’, stacked=True)
plt.title(‘Stock Change Frequency by Day of Week’)
plt.xlabel(‘Day of Week’)
plt.ylabel(‘Frequency’)
plt.show()

“”"## 4.15 pandas分组与聚合

  • 分组:将相同的类别分为一组 (groupby)
  • 聚合:将分组后的数据,进行统计运算 (sum, mean…)

“”"

import pandas as pd

df = pd.DataFrame({
‘Name’: [‘Alice’, ‘Bob’, ‘Charlie’, ‘David’, ‘Eve’],
‘Department’: [‘HR’, ‘IT’, ‘IT’, ‘HR’, ‘Marketing’],
‘Salary’: [50000, 60000, 70000, 52000, 45000]
})

按部门分组并计算每个部门的平均薪资

department_group = df.groupby(by=“Department”)[“Salary”].mean()

department_group = df[“Salary”].groupby(by=df[“Department”]).mean()
print(department_group)

“”"## 电影数据分析案例

分析电影数据

数据源:https://www.kaggle.com/datasets/PromptCloudHQ/imdb-data?resource=download

  • 1.电影分数的平均分?

  • 2.总共有多少位导演?

  • 3.对于这些电影,如何查看Rating的分布情况,如何以合适的方式呈现数据?

  • 4.对于这些电影,如何统计电影的分类情况?

“”"

import pandas as pd
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

导入数据

点击左侧的文件图标,再点击窗口中的循环drive标志,导入drive文件,然后复制路径

df = pd.read_csv(‘/content/drive/MyDrive/colab data/IMDB-Movie-Data.csv’)
df.head(2)

---------------------------------------------

1.评分的平均分

print(df[“Rating”].mean())

---------------------------------------------

2.导演人数

print(np.unique(df[“Director”]).size)

---------------------------------------------

3.Rating的分布情况-直方图

fig, ax = plt.subplots(layout=‘constrained’, figsize=(20,8))

data = df[“Rating”]

ax.hist(data, bins=20, alpha=0.7, color=‘blue’, edgecolor=‘black’)

plt.xticks(np.linspace(data.min(), data.max(), 21))

ax.set_title(‘Rating distribution’)

ax.set_xlabel(‘Value Rating’)

ax.set_ylabel(‘Star’)

ax.grid(True, which=‘both’, axis=‘both’, linestyle=‘–’, alpha=0.5)

plt.show()

---------------------------------------------

4.统计电影的分类情况

拿到每个电影的分类,得到去重后的所有电影类别

each_movie = [i.split(“,”) for i in df[“Genre”]]
movie_genre = sorted(list(set([j for i in each_movie for j in i])))
total_movie = len(df[“Title”])
total_genre = len(movie_genre)

创建一个新的表,一行为一部电影,一列为一个类别,以0或1区分是否是这个类别

count_df = pd.DataFrame(np.zeros(shape=[total_movie,total_genre],dtype=“int32”), index=df[“Title”], columns=movie_genre)

根据索引进行+1

for i in range(0,total_movie):
m_name = df.loc[i][“Title”]
m_genre = each_movie[i]
count_df.loc[m_name][m_genre] = 1

sum_df = count_df.sum().sort_values(ascending=False)

柱状图展示

categories = sum_df.index
values = sum_df.values

fig, ax = plt.subplots(layout=‘constrained’, figsize=(20,8))
ax.bar(categories, values, align=‘center’, color=plt.cm.tab20.colors, edgecolor=‘black’)

ax.set_title(‘Values per Genre’)
ax.set_xlabel(‘Genre’)
ax.set_ylabel(‘Values’)

for i, value in enumerate(values):
ax.text(i, value+4, str(value), ha=‘center’)

ax.grid(True, axis=‘both’, linestyle=‘–’, alpha=0.5)
plt.show()

如果有所帮助请给个免费的赞吧~有人看才是支撑我写下去的动力!

声明:
本文仅用作学习记录和交流

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/896611.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

算法打卡 Day43(动态规划)-背包问题 + 分割等和子集

文章目录 0-1 背包问题理论基础0-1 背包问题滚动数组Leetcode 416-分割等和子集题目描述解题思路 0-1 背包问题理论基础 0-1 背包一般的题目要求是给定不同重量不同价值的物品&#xff0c;每个物品只有一个&#xff0c;已知背包中最大的负重&#xff0c;求在此限制条件下背包中…

达那福发布新品音致系列:以顶尖降噪技术,开启清晰聆听新篇章

近日&#xff0c;国际知名助听器品牌达那福推出其最新研发的音致系列助听器。该系列产品旨在通过顶尖的声音处理技术&#xff0c;直面助听器市场中普遍存在的挑战——如何在噪声环境中提供清晰的语音辨识。 根据助听器行业协会2022年的调查数据&#xff0c;高达86%的佩戴者认为…

数据结构——二叉树的基本操作及进阶操作

前言 介绍 &#x1f343;数据结构专区&#xff1a;数据结构 参考 该部分知识参考于《数据结构&#xff08;C语言版 第2版&#xff09;》116 ~ 122页 及 《数据结构教程》201 ~ 213页 重点 树的基本实现并不难&#xff0c;重点在于对递归的理解才是树这部分知识带来的最大收…

jmeter学习(8)界面的使用

1、新建test plan 3、 打开文件 4、保存 5、剪切 6、复制 7、粘贴 8、所有线程组展开 9、所有线程组收缩 10、置灰&#xff0c;操作后无法使用 11、执行 13、清空当前线程组结果 14、清空所有线程组结果 15、函数助手 搜索&#xff0c;可以用于搜索某个请求&#x…

Java基于微信小程序的健身小助手打卡预约教学系统(源码+lw+部署文档+讲解等)

项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不是配置文件。Spring Boot 通过自动化配置和约…

使用OpenCV进行视频边缘检测:案例Python版江南style

1. 引言 本文将演示如何使用OpenCV库对视频中的每一帧进行边缘检测&#xff0c;并将结果保存为新的视频文件。边缘检测是一种图像处理技术&#xff0c;它可以帮助我们识别出图像中不同区域之间的边界。在计算机视觉领域&#xff0c;这项技术有着广泛的应用&#xff0c;比如物体…

登录时用户名密码加密传输(包含前后端代码)

页面输入用户名密码登录过程中&#xff0c;如果没有对用户名密码进行加密处理&#xff0c;可能会导致传输过程中数据被窃取&#xff0c;就算使用https协议&#xff0c;在浏览器控制台的Request Payload中也是能直接看到传输的明文&#xff0c;安全感是否还是不足。 大致流程&a…

redis—cluster集群

一&#xff1a;Redis Cluster特点 多主多从&#xff0c;去中心化&#xff1a;从节点作为备用&#xff0c;复制主节点&#xff0c;不做读写操作&#xff0c;不提供服务不支持处理多个key&#xff1a;因为数据分散在多个节点&#xff0c;在数据量大高并发的情况下会影响性能&…

Columns Page “列”页面

“列”页提供了列管理工具&#xff0c;其中包括用于添加和删除列的按钮、显示绑定数据源中字段名称的列表框以及网格列、提供对所选列属性的访问的属性网格。 Columns 页面提供 Column properties &#xff08;列属性&#xff09;、Column options &#xff08;列选项&#xff…

Electron-(三)网页报错处理与请求监听

在前端开发中&#xff0c;Electron 是一个强大的框架&#xff0c;它允许我们使用 Web 技术构建跨平台的桌面应用程序。在开发过程中&#xff0c;及时处理网页报错和监听请求是非常重要的环节。本文将详细介绍 Electron 中网页报错的日志记录、webContents 的监听事件以及如何监…

如何使用JMeter进行性能测试的保姆级教程

性能测试是确保网站在用户访问高峰时保持稳定和快速响应的关键环节。作为初学者&#xff0c;选择合适的工具尤为重要。JMeter 是一个强大的开源性能测试工具&#xff0c;可以帮助我们轻松模拟多用户场景&#xff0c;测试网站的稳定性与性能。本教程将引导你通过一个简单的登录场…

微信小程序canvas 生成二维码图片,画图片,生成图片,将两个canvas结合并保存图片

需求实现步骤如下 先定义两个canvas一个canvas myQrcode画二维码的图片另一个canvas mycanvas画一个背景图&#xff0c;并把二维码画到这个canvas上&#xff0c;mycanvas这个canvas生成一张图片&#xff0c;返回图片的临时路径最后保存图片到手机 首先wxml,新版微信小程序can…

Java之继承抽象类用法实例(三十一)

简介&#xff1a; CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a; 多媒体系统工程师系列【…

使用Matplotlib绘制箱线图:详细指南与示例

在数据分析和可视化领域&#xff0c;箱线图&#xff08;Box Plot&#xff09;是一种强大的工具&#xff0c;用于展示数据的分布特征&#xff0c;包括中位数、四分位数、异常值等。本文将详细介绍如何使用Matplotlib库在Python中绘制箱线图&#xff0c;并通过一个实际的血压数据…

从0开始linux(13)——进程(4)进程空间地址(1)

欢迎来到博主的专栏&#xff1a;从0开始linux 博主ID&#xff1a;代码小豪 文章目录 进程空间地址 还记得博主在之前介绍子进程时说过的话吗&#xff1f;子进程与父进程共享代码&#xff0c;而数据却不共享&#xff1b;这很好理解&#xff0c;因为子进程和父进程是不同的进程&a…

Java线程安全集合之COW

概述 java.util.concurrent.CopyOnWriteArrayList写时复制顺序表&#xff0c;一种采用写时复制技术&#xff08;COW&#xff09;实现的线程安全的顺序表&#xff0c;可代替java.util.ArrayList用于并发环境中。写时复制&#xff0c;在写入时&#xff0c;会复制顺序表的新副本&…

K8S调度不平衡问题分析过程和解决方案

不平衡问题排查 问题描述&#xff1a; 1、业务部署大量pod(据反馈&#xff0c;基本为任务型进程)过程中&#xff0c;k8s node内存使用率表现不均衡&#xff0c;范围从80%到百分之几&#xff1b; 2、单个node内存使用率超过95%&#xff0c;仍未发生pod驱逐&#xff0c;存在node…

Janus:开创统一的多模态理解和生成框架

Janus是DeepSeek开源的多模式自回归框架&#xff0c;统一了多模态理解和生成&#xff0c;既可以理解图片内容又可以生成图片。 1.简介 Janus 是一种新颖的自回归框架&#xff0c;它将多模态理解和生成统一起来。它通过将视觉编码解耦为单独的路径来解决以前方法的局限性&…

jmeter发送post请求

在jmeter中&#xff0c;有两种常用的请求方式&#xff0c;get和post.它们两者的区别在于get请求的参数一般是放在路径中&#xff0c;可以使用用户自定义变量和函数助手等方式进行参数化&#xff0c;而post请求的参数不能随url发送&#xff0c;而是作为请求体提交给服务器。而在…

OpenWRT 和 Padavan 路由器配置网络打印机 实现远程打印

本文首发于只抄博客&#xff0c;欢迎点击原文链接了解更多内容。 前言 之前有给大家介绍过 Armbian 安装 CUPS 作为打印服务器&#xff0c;像是 N1 盒子、玩客云&#xff0c;甚至是随身 WiFi 都可以通过 CUPS 来进行打印。但是有些朋友不想专门为打印机添置一个设备&#xff0…