目录

b站python基础学习笔记

vs code中配置python虚拟环境

一、NumPy

1.概念

2.数值文件的读写

3.ndarray类型

二、Pandas

1.概念

2.一维数据结构Series

3.二维数据结构 DataFrame

4.DataFrame的常用操作

三、Python绘图

1.Matplotlib

2.Plotly

3.PyEcharts

总结

四、FastAPI 

 FastAPI项目

工具:

项目结构:

app与服务: 

 路由

示例

 路由的处理

路径参数(动态路由)

查询参数 

body

 路由和报文的对应关系

 五、必须知道的衍生

从文件分离,到路由分类集中

中间件

数据存储:从内存到数据库

 六、-DB in FastAPI


b站python基础学习笔记

码奇码的个人空间-码奇码个人主页-哔哩哔哩视频 


vs code中配置python虚拟环境

可参考教程:vscode使用python虚拟环境配置详解_哔哩哔哩_bilibili

注:关于vscode中ipynb选择内核时找不到内核(输入路径也不行)的问题解决

更新下jupyter(可更改为预发布版本),再重启vscode就可以选择到内核了

参考:关于vscode连接服务器后运行ipynb文件要求选择“....ipynb“的内核时找不到任何可用的内核的解决方案 - 知乎


以下教程来自b站

03 NumPy_哔哩哔哩_bilibili

一、NumPy

1.概念

  • 线性代数工具包,用于基本的线性代数和数值计算
  • 主要用于处理大规模的数组和矩阵数据,以及对这些数据执行各种数学运算
  • 许多高级包的依赖基础,如pytorch(神经网络)、pandas(数据处理)
  • 底层是C实现,在CPU上做了优化,效率很高
  • NumPy核心:ndarray、矢量化运算、广播机制

2.数值文件的读写

实验室数据常以文件存储(乃至于数据库),读写方法:二进制文件、文本文件

  • 文本文件: .txt 和 .csv文件
  • 二进制文件: .npy文件  (速度快)

numpy 读写文件的两种方法

#对 txt,csv的文本文件读写
np.savetxt('array.csv',arr,delimiter=',')
np.loadtxt('array.csv',delimiter=',')
#对 npy 的二进制文件读写
np.save('array.npy',arr)
np.load('arry.npy')

3.ndarray类型

概念:ndarray(n dimensional array)(n维数组),一种numpy数组的实现,支持更多的数学运算

  • numpy包主要操作对象是ndarray类型的对象,而array是它的一个“从python list 创建 ndarray"的方法

np.array 注意这是个函数  # Callable [ [ list ] , np.ndarray ]

np.ndarray 注意这是个类型 #class

  •  其中 Callable [ [ list ] , np.ndarray ] 表达的是,在numpy的源文件中,array()很可能是这样编写的:
def array(args: list) -> ndarray: #传入的参数args是list类型
  ...
  return result: ndarray
#array()函数的作用:把python的list转换成numpy的ndarray类型
#涉及类型标注,让项目更严谨,类型出错时候会提醒报错

总结:从类型上看,ndarray和np.array并不是一回事


04 Pandas_哔哩哔哩_bilibili

二、Pandas

1.概念

  • 数据分析工具,核心代码是用cython和c编写,灵活易用高效
  • pandas(衍生自panel data) :高性能、易用的数据分析包,提供易于使用的数据结构和数据分析工具,特别适合处理表格型数据(如excel\数据库表等)
  • pandas的两个核心数据类型:series、DataFrame
  • 相对于数据库,pandas适用于中小型数据,其crud(creat、read、update、delete)与db(数据库)大致相同
  • 使用时数据是存在内存上的,使用时需要注意否则数据量太大会导致电脑卡死

2.一维数据结构Series

Series:具有索引一维数组的结构,每个数据项都可以通过标签访问

Series示例:

import pandas as pd
#从列表创建series
s1=pd.Seires([10,20,30,40],index=['a','b','c','d'])
#从字典创建
s2=pd.Series({'a':10,'b':20,'c':30,'d':40})
print("s1['a']:",s1['a'])
print("s2['b']:",s2['b'])

output

s1['a']: 10
s2['b']: 20


3.二维数据结构 DataFrame

DataFrame:一个二维表格型的数据结构。可以理解为一个表格,每一行每一列都有自己的标签(索引和列名)

DataFrame

# 从二维列表创建 DataFrame
data1 = [
    [1, 'Alice', 24, 'New York'],
    [2, 'Bob', 27, 'Los Angeles'],
    [3, 'Charlie', 22, 'Chicago'],
    [4, 'David', 3, 'Houston']
]

df1 = pd.DataFrame(data1, columns=['ID', 'Name', 'Age', 'City'])	# 不指定columns默认为从0递增的序列
# 从字典创建 DataFrame
data2 = {
    'ID': [1, 2, 3, 4],
    'Name': ['Alice', 'Bob', 'Charlie', 'David'],
    'Age': [24, 27, 22, 32],
    'City': ['New York', 'Los Angeles', 'Chicago', 'Houston']
}

df2 = pd.DataFrame(data2)

 output


4.DataFrame的常用操作

1)文件读写:分为csv和excel文件两种

#csv
df=pd.read_csv('sample_data.csv',sep=',')
df.to_csv('output.csv',index=False)

#excel
df=pd.read_excel('sample_data.xlsx')
df.to_excel('output.xlsx')

2)修改操作

pandas的设计中,具有修改的操作通常会有inplace参数默认是False,即不会修改原数据,而是返回一个新的对象,故如果inplace为false时,需要用一个新的变量接住新的对象。inplace参数

#inplace=True时,修改的数据会覆盖原数据
df.drop('column1',axis=1,inplace=True)#删除一列
#如果inplace为false,不会修改原数据,需要用一个新的变量接住这个修改,如下
a=df.drop('column1',axis=1,inplace=False)

3)查看DataFrame的数据信息 常用的数据索引方式多行/列索引、条件索引

#多行/列索引
df.loc[2:4,'columnl']  #假设行标签是2到4,选择名称为columnl的列(location通过标签名称来定位)
df.iloc[2:4,7]    # 2到3行,选择第8列(int location通过编号来定位)

# 多列
print(df[['年龄', '成绩']])  # 选择多个列

#条件索引
df[df['columnl']>10] #列值大于10的行
df[(df['age']>30)&(df['score']>300)] #要用位运算操作符,不能用and

4)常用的数据统计方法

import pandas as pd
data = {
    '姓名': ['张三', '李四', '王五', '赵六', '钱七', '孙八', '周九', '吴十', '郑十一', '马十二'],
    '年龄': [18, 19, 20, 21, 22, 23, 24, 25, 26, 27],
    '成绩': [85, 92, 78, 89, 95, 87, 90, 93, 80, 88]
}

df = pd.DataFrame(data)

# 计数
df['年龄'].count()  # 计算column1中的非空值数量

# 众数
df['年龄'].mode()  # 找出column1中的众数

# 最值
df['年龄'].min()  # 计算column1的最小值
df['年龄'].max()  # 计算column1的最大值

# 四分位点
df['成绩'].quantile(0.25)  # 计算column1的第25百分位数

# 求和/均值
df['成绩'].sum()  # 计算column1的和
df['成绩'].mean() # 计算column1的平均值

# 标准差/方差
df['成绩'].std()  # 计算column1的标准差
df['成绩'].var()  # 计算column1的方差

5)常用的数据处理操作

import pandas as pd
data = {
    '姓名': ['张三', '李四', '王五', '赵六', '钱七', '孙八', '周九', '吴十', '郑十一', '马十二'],
    '年龄': [18, 19, 20, 21, 22, 23, 24, 25, 26, 27],
    '成绩': [85, 92, 78, 89, 95, 87, 90, 93, 80, 88]
}

df = pd.DataFrame(data)

# 增
df.loc[5] = ['Tom', 25, 90]  #
df['总成绩'] = df['成绩']  # 新增一列

# 删
df.drop('总成绩', axis=1, inplace=True)  # 删除一列
df.drop(0, axis=0, inplace=True)  # 删除第一行

# 改
df.at[0, '成绩'] = 10  # 修改特定单元格的值
df['成绩'] = df['成绩'].replace(10, 20)  # 将column1中的10替换为20

# 批量处理
df.apply(lambda x: x * 2, axis=0)	# axis=0按列处理,axis=1按行处理

# 重命名
df.rename(columns={'年龄': '生理年龄'}, inplace=True)  # 重命名列
df.rename(index={0: 12}, inplace=True)  # 重命名行

# 缺失值处理
df.dropna()		# 删除包含缺失值的行
df.fillna(0)	# 将缺失值填充为0
df.fillna({'成绩': df['成绩'].mean()}, inplace=True)  # 用平均值填充缺失值

# 去重
df.drop_duplicates(inplace=True)  # 删除重复行

# 排序
df.sort_values(by='成绩', ascending=True)	# 按column1升序排序
df.sort_index(axis=0, ascending=False)			# 按行索引降序排序

# 分组
df.groupby('成绩').sum()  # 按column1分组并求和
df.groupby(['成绩', '生理年龄'])	# 按多个列分组

for (name, gp) in df.groupby('成绩'):  # 分组遍历
  pass

df = pd.DataFrame(data)

# 合并
pd.merge(df, df, on='成绩')	# 基于“key”列合并两个DataFrame
pd.concat([df, df], axis=0)	# 在行上合并
pd.concat([df, df], axis=1)	# 在列上合并

# 可视化
df['成绩'].plot(kind='line')  # 折线图
df.plot(kind='bar')  # 柱状图
df.plot(kind='scatter', x='成绩', y='年龄')  # 散点图

三、Python绘图

matplotlib、plotly、pyecharts

参考教程:05 python 绘图_哔哩哔哩_bilibili

1.Matplotlib

Matplotlib是目前最流行和广泛使用的python绘图模块,import as plt

特点:

  • 灵活、可以更好控制细节,比如纸条样式、颜色等
  • 社区活跃,文档完善

适用场景:

  • 科学研究和数据分析中的图表制作
  • 需要高度定制化图形的应用

 编码模式:

  1. plt.figure() 创建Figure对象
  2. plt.{any}chart() 传入数据绘制具体的{any}图表
  3. plt.{any}seter() 调节图表的参数和布局
  4. plt.show() 显示图表或者 plt.savefig() 保存图表

注意: plt的操作对象是图,如果不指明操作对象,那么操作的是全局的默认图,如果有多张图,全局默认操作最后一张图

另:Seaborn同样也是很流行的科学图表制作模块,其对matplotlib进行了一层封装,提供了更简洁的接口和更美观的默认样式,具体的编码模式与matplotlib相同

import matplotlib.pyplot as plt

# 示例数据:一个月内每天的销售量
days = list(range(1, 31))  # 1到30天
sales = [250, 300, 280, 310, 290, 330, 340, 360, 300, 310,
         280, 350, 360, 390, 370, 400, 420, 430, 410, 390,
         400, 420, 430, 440, 450, 460, 480, 500, 490, 520]

# 创建图形对象
plt.figure(figsize=(10, 6))

# 绘制柱状图
plt.bar(days, sales, color='lightblue', alpha=0.7, label='Daily Sales')

# 绘制折线图
plt.plot(days, sales, color='blue', marker='o', linestyle='-', label='Trend')

# 添加标题和标签
plt.title('Daily Sales for a Month')
plt.xlabel('Day')
plt.ylabel('Sales')
plt.legend()

# 显示图形
plt.show()


 

2.Plotly

plotly是一个交互可视化工具,支持创建交互式的图表,如缩放、平移等操作

特点:

  • 提供了丰富的交互功能
  • 能够在线分享图表

适用场景:需要用户交互的数据展示 

编码模式:

  1. 用 chart=go.{any}chart() 传入数据绘制具体的{any}图表 (建个chart图表接住数据)
  2. 用 fig=go.Figure(data=[chart]) 创建Figure对象并将图表渲染到Figure上(建个图像figure)
  3. 用 fig.update_layout() 设置图表的参数和布局
  4. 用 fig.show() 显示图表或者 fig.write.image() 保存图表
import plotly.graph_objects as go

# 示例数据:一个月内每天的销售量
days = list(range(1, 31))
sales = [250, 300, 280, 310, 290, 330, 340, 360, 300, 310,
         280, 350, 360, 390, 370, 400, 420, 430, 410, 390,
         400, 420, 430, 440, 450, 460, 480, 500, 490, 520]

# 创建柱状图
bar = go.Bar(
    x=days,
    y=sales,
    name='Daily Sales',
    marker=dict(color='lightblue'),
    opacity=0.7
)

# 创建折线图
line = go.Scatter(
    x=days,
    y=sales,
    mode='lines+markers',
    name='Trend',
    marker=dict(color='blue')
)

# 创建图形对象
fig = go.Figure(data=[bar, line])

# 添加标题和标签
fig.update_layout(
    title='Daily Sales for a Month',
    xaxis_title='Day',
    yaxis_title='Sales',
    legend_title='Legend'
)

# 显示图形
fig.show()

 

图表可以交互,如框选放大,或者鼠标放到折线点会显示数值 


 

3.PyEcharts

PyEcharts 是一个基于 ECharts 的 Python 库,ECharts 是百度推出的一个纯 JavaScript 的图表库。

特点:

  • 强大的图表类型支持
  • 与Echarts无缝集成
  • 自动生成HTML文件

适用场景:

  • Web开发中的数据可视化
  • 需要用户交互的数据展示
  • 与JavaScript的集成

编码模式:

  1. 用 chart=chart()根据传入数据绘制具体的{any}图表 
  2. 针对chart进行额外的设置
  3. 用 chart.render()导出为html文件 或chart.render_notebook() 直接在jupyter notebook中显示 (render渲染器的意思)
rom pyecharts.charts import Bar, Line
from pyecharts import options as opts

# 示例数据:一个月内每天的销售量
days = list(range(1, 31))
sales = [250, 300, 280, 310, 290, 330, 340, 360, 300, 310,
         280, 350, 360, 390, 370, 400, 420, 430, 410, 390,
         400, 420, 430, 440, 450, 460, 480, 500, 490, 520]

# 创建柱状图
bar = (
    Bar()
    .add_xaxis(days)
    .add_yaxis("Daily Sales", sales, color="lightblue")
    .set_global_opts(
        title_opts=opts.TitleOpts(title="Daily Sales for a Month"),
        xaxis_opts=opts.AxisOpts(name="Day"),
        yaxis_opts=opts.AxisOpts(name="Sales"),
      legend_opts=opts.LegendOpts(pos_top="5%")
    )
)

# 创建折线图
line = (
    Line()
    .add_xaxis(days)
    .add_yaxis("Trend", sales, is_smooth=True, linestyle_opts=opts.LineStyleOpts(color="blue"))
)

# 将两个图表结合到一起
bar.overlap(line)

# 显示图形
bar.render_notebook()

 图表可交互


总结

通常在绘图的时候都会是这样的流程:

  1. 准备数据
  2. 使用第三方模块将数据绘制成图
  3. 调整图的参数和布局
  4. 显示或者保存绘制好的图像

三个库的选择简单来说:

  • 如果你需要的是一个简单但强大的绘图工具,可以选择 Matplotlib
  • 如果你希望创建交互式的图表,可以选择 Plotly
  • 而如果你正在开发 Web 应用并且想要快速集成图表,可以选择 PyEcharts

四、FastAPI 

参考教程:06 FastAPI_哔哩哔哩_bilibili

FastAPIhttps://fastapi.tiangolo.com/zh/FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框架,使用 Python 并基于标准的 Python 类型提示。


 FastAPI项目

  •  工具、项目结构、app与服务
工具:
  • FastAPI 包和 uvicorn 包
pip install fastapi
pip install "uvicorn[standard]"

uvicorn 是一个后端框架无关的(不用fastapi,换别的后端框架,还是可用用uvicon启动),用于启动 HTTP 服务的工具

也就是说,你需用 Uvicorn 来运行你的 FastAPI 应用

项目结构:

一个典型的 FastAPI 项目应该包含以下文件结构:

fastapi_project/
├── app/
│ ├── __init__.py
│ ├── main.py                              # 主应用程序入口
│ ├── api/                                     # API 路由
│ │ ├── __init__.py
│ │ └── endpoints/                       # 具体的 API 端点
│ ├── models/                              # 数据模型
│ ├── schemas/                           # Pydantic 模式
│ ├── services/                            # 业务逻辑层
│ └── database/                          # 数据库连接与管理

├── tests/                                    # 测试文件,正规开发会用到
│ ├── __init__.py
│ └── test_main.py                     # 主要测试文件

├── requirements.txt                   # 项目依赖,用 pip-install -r requirements.txt 来进行
装包
└── README.md                       # 项目说明文件

app与服务: 
from fastapi import FastAPI

app=FastAPI()

@app.get("/")
async def root():
    return {"meaasge":,"Hello World"}

基础FastAPI应用,请查看main.py(教程up主给的学习文件)

  • @app.get : python 的装饰器,用于定义路由。用装饰器修饰的函数会被处理一次。这里的处理指将函数注册到 app 的路由表中
  • async 用于异步操作,几乎所有网络相关的操作都是异步的。详情见 public 编程语言 language 和 网络 network 部分。
uvicorn {入口文件名}:app --reload

注意:

  • 如果没加--reload,你在py文件中的修改并不会实时更新,还处于更改前的项目,要更新只能先通过 ctrl+c 强行打断该项目,然后重新加载新项目
  • 加了--reload就可以实施更新,改后记得ctrl+s,再去刷新网页就可以更新

以上案例说明了,当配置了 app 最基础的部分后(大部分配置都可以通过对app进行设置实现),我们可以通过访问服务器根路由/ 来得到文本“Hello World”。这就是用 FastAPI 开发的最简单的基于 HTTP 的后端服务(server)应用。

注意:

  • 所有后端框架在开发中,测试运行时的ip通常是localhost(也即127.0.0.1,本机ip地址),FastAPI端口的配置默认是8000,也可以手动配置
  • 大部分配置都可以通过对app进行设置实现 

运行时出现的问题:

Error loading ASGI app. Could not import module "main".

解决方法:请在文件名前面添加文件夹名

参考:FastAPI抛出一个错误(加载ASGI应用程序时出错)。无法导入模块"api")-腾讯云开发者社区-腾讯云


 路由

以某站为例:

xxx.com/ # 首页
xxx.com/about # 关于页
xxx.com/about/team # 团队页
xxx.com/login # 登录页
xxx.com/user/:username # 用户页
xxx.com/video/:id # 视频页
xxx.com/search?keyword=value # 搜索页

其中:xxx.com 是网站的域名,后面的部分称为“路由”(route )

  • /about 、/about/team 为一级、二级路由中文常作相关/关于页用于展示网站、网站团队的静态图文信息
  • /login 为登录页在输入用户名密码通过登录验证后,服务器将返回给客户端(浏览器,在用户机器上)一个 token(凭证),以便用户在后续访问时验证身份。token 常用浏览器 cookie 来存储
  • cookie:一种在用户浏览器上存储少量数据的技术。本质是临时文件
  • /user 为用户页用于展示用户的个人信息。其中:username 部分为动态路由,意味着/user 后面可以跟任意的用户名(在地址栏中任何符合该格式的链接都能被匹配识别到该路由,而非其它路由上)。显然,不同用户访问某用户页时,分为本人和非本人两种情况,它们的操作逻辑也分为查看他人信息与查看和修改本人信息。他人和本人通过登陆后获取的 token 来区分
  • /video 为视频页用于展示视频内容。其中:id 部分为动态路由,意味着/video 后面可以跟任意的视频 ID
  • /search 为搜索页用于搜索关键字相关的内容。/search 跟随的是http的查询参数(以? 开头,由键值对key=value 来提供)

至此我们清楚了一般 Web 应用后端的需求:

  • 根据 url 链接来处理内含的不同需求,并返回给客户端。
  • 我们把处理这些需求的功能集中到一个进程,挂在在 server(服务器)上,称为 service(服务,对操作系统而言,区别于其它进程,一种进程类型)。 
  •  url:统一资源定位符,以http:// 或https:// 开头(如 http://www.example.com)
  • uri:统一资源标识符,以{example}: 开头(如 mysql://localhost/test)
  • 两者都表现为链接
示例
from fastapi import FastAPI
from pydantic import BaseModel

# 创建一个FastAPI实例
app = FastAPI()

# 根路由
@app.get("/")
async def root():
    """返回一个简单的欢迎信息。"""
    return {"message": "Hello World"}

# 用户页面 - 使用路径参数
@app.get("/user/{username}")
async def user_page(username: str):
    """根据提供的用户名返回用户信息。"""
    return f"the user's name is: {username}"

# 搜索功能 - 使用查询参数
@app.get("/search")
async def search(keyword: str = ""):
    """根据提供的关键词返回搜索结果。"""
    return f"用户搜索了关键词: {keyword}"

根路由:

用户页面:

搜索功能:


 路由的处理

 通过 url 发送来的请求,做不同处理。可以认为处理路由就是后端业务的核心

路径参数(动态路由)

FastAPI 可以很方便地处理这种“动态网址”,我们只需要在路由中指定一个参数(比如 :username )。
比如对于 /user/:username
当用户访问 http://localhost:8000/user/emily 时,页面会显示“the user's name is: emily”。

# 用户页面 - 使用路径参数
@app.get("/user/{username}")
async def user_page(username: str):
    """根据提供的用户名返回用户信息。"""
    return f"the user's name is: {username}"

查询参数 

比如在请求头的 URL 里添加 QueryParams(查询参数)。
查询字符串是键值对的集合,这些键值对位于 URL 的 ? 之后,以 & 分隔。
比如对于 /search?keyword=value
当用户访问 http://localhost:8000/search?keyword='google' 时,页面会显示“用户搜索了关键
词: google”。

# 搜索功能 - 使用查询参数
@app.get("/search")
async def search(keyword: str = ""):
    """根据提供的关键词返回搜索结果。"""
    return f"用户搜索了关键词: {keyword}"

body
  • 上面我们一直用的是@app.get 装饰器,注册 GET 请求的路由。
  • 对于 POST 请求,我们可以获取到请求体中的数据。
  • 比如对于 /login
  • 这里突然从@app.get 切换到@app.post 的理由,后续马上介绍
# 登录功能 - 使用POST请求体
@app.post("/login")
async def login(form_data: LoginForm):
    """验证登录信息并返回相应的响应。"""
    if form_data.username == "admin" and form_data.password == "123456":
        # 如果用户名和密码正确,则返回登录成功的响应
        token = {"status": "login", "username": form_data.username}
        return token
    else:
        return {"error": "用户名或密码错误"}
  • 注意:token 往往是临时的,动态生成的,加密过后的。上述例子只是简化,记得用专门的token 生成用的加密方法(函数)。
  • 当用户发送 POST 请求到 /login 时,我们能分情况返回登陆成功时的 token 或错误信息。

 路由和报文的对应关系

一个典型的 HTTP 请求报文(Request)包含如下内容:

  1. HTTP method 常用的有 GET、POST(PUT、DELETE、HEAD、OPTIONS、TRACE)
  2. @app.get 明确了某路由下的特定类型(此处为 GET),同一路由可以有不同类型的请求。
  3. GET 和 POST 的选择依据是:GET 请求的信息往往放在 URL 里(HTTP 标准设计上 GET 不包含body),明文 URL 并不安全且信息量少(URL 长度限制);POST 请求的信息放在 body 里,信息量更大且安全性更高。
  4. 路径参数在请求信息的 URL 中
  5. 查询参数在请求信息的 URL 末尾,以? 开头,多个参数以& 分隔
  6. body 在请求体中,和其等价

 五、必须知道的衍生

从文件分离,到路由分类集中

project文件夹(learning目录下(此为本人的学习笔记路径,详细笔记可去文章开头的b站链接up主那里找)

中间件

  • 大致是讲如何在路由动作之前(或之后),统一加一个操作。这个被加在路由之前的操作,称为中间件(Middleware)
  • 比如在每个路由上加一个 looger,记录每个请求的日志
  • 具体查看文档

数据存储:从内存到数据库

内存存储

my_data = []
@app.post("/add_data")
async def add_data(data: DataModel):
    my_data.append(dat

 当数据量过大时,改为数据库存储

db = DataBase.connect(...)
@app.post("/add_data")
async def add_data(data: DataModel):
    db.insert(db_data

 六、-DB in FastAPI

  • SQLite:轻量数据库
  • SQLite3 是 SQLite 的一个稳定版本,内置于 Python 中

教程:07 DB in FastAPI 和 python 项目指导_哔哩哔哩_bilibili

 

更多推荐