目录
基础知识
Pandas是Python中的一个强大数据处理和分析工具,特别适用于表格数据(如Excel或CSV文件)。它提供了两种主要的数据结构:Series
和 DataFrame
。快速掌握Pandas需要理解这些数据结构及其常用操作。
基本数据结构
-
Series:
-
类似于一维数组,但有标签(索引)。
-
python 复制代码 import pandas as pd # 创建一个Series s = pd.Series([1, 3, 5, 7, 9], index=['a', 'b', 'c', 'd', 'e']) print(s)
-
DataFrame:
-
类似于二维表格数据,每列可以有不同的数据类型。
python
复制代码
import pandas as pd
# 创建一个DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie'], 'Age': [25, 30, 35], 'City': ['New York', 'Los Angeles', 'Chicago']}
df = pd.DataFrame(data)
print(df)
常用操作
-
读取数据:
-
读取CSV文件。
python 复制代码 df = pd.read_csv('data.csv')
-
-
查看数据:
-
查看前几行数据。
python 复制代码 print(df.head())
-
查看数据结构和类型。
python 复制代码 print(df.info()) print(df.describe())
-
-
选择数据:
-
选择一列。
python 复制代码 print(df['Name'])
-
选择多列。
python 复制代码 print(df[['Name', 'Age']])
-
选择行(基于标签)。
python 复制代码 print(df.loc[0])
-
选择行(基于位置)。
python 复制代码 print(df.iloc[0])
-
-
过滤数据:
-
根据条件过滤数据。
python 复制代码 print(df[df['Age'] > 30])
-
-
添加和删除数据:
-
添加新列。
python 复制代码 df['Salary'] = [50000, 60000, 70000] print(df)
-
删除列。
python 复制代码 df = df.drop(columns=['Salary']) print(df)
-
删除行。
python 复制代码 df = df.drop(0) print(df)
-
-
数据处理:
-
缺失值处理。
python 复制代码 df = df.fillna(0) # 用0填充缺失值 print(df)
-
数据分组。
python 复制代码 grouped = df.groupby('City').mean() print(grouped)
-
-
导出数据:
-
导出到CSV文件。
python 复制代码 df.to_csv('output.csv', index=False)
-
示例代码
假设我们有一个名为 students.csv
的CSV文件,内容如下:
csv
复制代码
Name,Age,Grade
Alice,24,A
Bob,22,B
Charlie,23,A
David,22,C
Eve,24,B
我们将用Pandas进行一些操作:
python
复制代码
import pandas as pd
# 读取CSV文件
df = pd.read_csv('students.csv')
# 查看数据
print(df.head())
# 查看数据结构和类型
print(df.info())
print(df.describe())
# 选择数据
print(df['Name']) # 选择一列
print(df[['Name', 'Grade']]) # 选择多列
print(df.loc[0]) # 选择第一行
print(df.iloc[0]) # 选择第一行(基于位置)
# 过滤数据
print(df[df['Age'] > 22])
# 添加新列
df['Passed'] = df['Grade'].apply(lambda x: x in ['A', 'B'])
print(df)
# 删除列
df = df.drop(columns=['Passed'])
print(df)
# 删除行
df = df.drop(0)
print(df)
# 缺失值处理
df = df.fillna('Unknown')
print(df)
# 数据分组
grouped = df.groupby('Grade').mean()
print(grouped)
# 导出到CSV文件
df.to_csv('students_processed.csv', index=False)
总结
-
理解Pandas数据结构:
Series
和DataFrame
。 -
常用操作:读取、查看、选择、过滤、添加、删除、处理和导出数据。
-
实际操作:通过实际示例代码练习上述操作。
课堂代码
QQ群文件“第4章 4--pandas.txt”
下载 jupyter notebook
pip install jupyter notebook
启动
jupyter notebook
# 导入 pandas 模块
import pandas as pd
# 导入数据
data = pd.read_csv('C:\\Users\\guojl\\Desktop\\example\\data\\score.txt')
# 或者
dt = pd.read_csv('C:/Users/guojl/Desktop/example/data/score.txt')
print(dt)
# 读取 txt 文件
txt_dt = pd.read_table('C:\\Users\\guojl\\Desktop\\example\\data\\score.txt', sep=',')
# 读取 excel 文件
excel_dt = pd.read_excel('C:\\Users\\guojl\\Desktop\\123.xlsx')
# 读取 html 文件
# html_dt = pd.read_html('C:\\Users\\guojl\\Desktop\\test.html')
# 字典转换为 DataFrame
dic1 = {'class':[211, 212, 213,214, 215], 'num':[34, 33, 35, 36, 37]}
dic_dt = pd.DataFrame(dic1)
print(dic_dt)
dic = [{'class':211, 'num':34},
{'class':212, 'num':33},
{'class':213, 'num':35},
{'class':214, 'num':36},
{'class':215, 'num':37}]
dic_dt = pd.DataFrame(dic)
# 存为 .csv 文件
dic_dt.to_csv('C:\\Users\\guojl\\Desktop\\example\\data_save\\csv_dt.csv')
# 存为 .xlsx 文件
dic_dt.to_excel('C:\\Users\\guojl\\Desktop\\example\\data_save\\excel_dt.xlsx')
# 存为 .json 文件
dic_dt.to_json('C:\\Users\\guojl\\Desktop\\example\\data_save\\json_dt.json')
# 导入 numpy 模块
import numpy as np
# 创建 20 行 5 列,由随机数组成的 DataFrame 对象
df = pd.DataFrame(np.random.rand(20, 5))
print(df)
# 元组
tup = (1, 2, 3)
# 创建一个 Series 对象
df = pd.Series(tup)
print(df)
# 列表
lst = [1, 2, 3]
# 创建一个 Series 对象
df = pd.Series(lst)
print(df)
# 一维数组
arr = np.array([1, 2, 3])
# 创建一个 Series 对象
df = pd.Series(arr)
print(df)
# 字典
dic = {'index0':1, 'index1':2, 'index2':3, 'index3':4}
# 创建一个 Series 对象
df = pd.Series(dic)
print(df)
# 由标量创建一个 Series 对象
df = pd.Series(10)
print(df)
# 指定index 创建一个 Series 对象
df = pd.Series("大数据", index=range(10, 20))
print(df)
# 指定index
lst = [1, 2, 3]
df = pd.Series(data=lst,index=["index1","index2","index3"])
print(df)
# 字典
dic = {'index0':1, 'index1':2, 'index2':3, 'index3':4}
df = pd.Series(dic,index=["index1","没有的"])
print(df)
# 索引重复,不建议
lst = [1,2,3]
df = pd.Series(lst, index=["索引相同"]*3)
print(df)
# 给 Series 命名
lst = [1,2,3]
df = pd.Series(lst, name='BigData')
print(df)
# 指定数据类型
lst = [1,2,3]
df = pd.Series(lst, dtype=np.float64)
print(df)
# date_range()是pandas中常用的函数,用于生成一个固定频率的DatetimeIndex时间索引。原型:
# date_range(start=None, end=None, periods=None, freq=None, tz=None, normalize=False, name=None, closed=None, **kwargs)
# 常用参数为start、end、periods、freq。
# start:指定生成时间序列的开始时间
# end:指定生成时间序列的结束时间
# periods:指定生成时间序列的数量
# freq:生成频率,默认‘D’,可以是’H’、‘D’、‘M’、‘5H’、‘10D’、…
# 还可以根据closed参数选择是否包含开始和结束时间,left包含开始时间,不包含结束时间,right与之相反。默认同时包含开始时间和结束时间。
# 函数调用时至少要指定参数start、end、periods中的两个。
df = pd.date_range('2023/4/10', '2023/5/10')
print(df)
# 指定开始时间和时间序列数量
df = pd.date_range('2023/4/10', periods=10)
print(df)
# 指定结束时间和时间序列数量
df = pd.date_range(end='2023/4/10', periods=10)
print(df)
# 指定开始时间、时间序列数量和频率
df = pd.date_range(start='2023/4/10', periods=10, freq='2D')
print(df)
# 指定结束时间、时间序列数量和频率
df = pd.date_range(end='2023/4/10', periods=10, freq='2D')
print(df)
# 指定起止时间和 closed 参数
df = pd.date_range(start='2023/4/10', end='2023/5/10', closed='left')
print(df)
# 时间序列做为索引,生成 Series 一维数组
dates = pd.date_range(start='2023/4/10', periods=10, freq='2D')
df = pd.Series(range(10), index=dates)
print(df)
# 时间序列做行索引,生成DateFrame二维数组
dates = pd.date_range(start='2023/4/10', periods=10, freq='2D')
df = pd.DataFrame(np.random.randn(10,5), index=dates, columns=list('ABCDE'))
print(df)
# 导入数据
df = pd.read_csv('C:/Users/guojl/Desktop/example/data/score.txt')
# 查看数据前10行
print(df.head(10))
# 导入数据
df = pd.read_csv('C:/Users/guojl/Desktop/example/data/score.txt')
# 查看数据最后10行
print(df.tail(10))
# 导入数据
df = pd.read_csv('C:/Users/guojl/Desktop/example/data/score.txt')
# 查看数据行数和列数
print(df.shape)
# 导入数据
df = pd.read_csv('C:/Users/guojl/Desktop/example/data/score.txt')
# 查看数据索引、类型和内存信息
http:df.info()
# 查看数据列的汇总统计
print(df.describe())
# 导入数据
df = pd.read_csv('C:/Users/guojl/Desktop/example/data/score.txt')
# 查看数据 score 列计数结果, 默认降序排列
print(df['score'].value_counts())
# 导入数据
df = pd.read_csv('C:/Users/guojl/Desktop/example/data/score.txt')
# 查看数据 score 列计数结果, 升序排列
print(df['score'].value_counts(ascending=True))
# 导入数据
df = pd.read_csv('C:/Users/guojl/Desktop/example/data/score.txt')
# 使用标准化 normalize=True 的方法,查看数据 score 计数占比
print(df['score'].value_counts(ascending=True, normalize=True))
# df.apply 用法,按列对数据进行操作
print(df.apply(pd.value_counts))
# 导入数据
df = pd.read_csv('C:/Users/guojl/Desktop/example/data/score.txt')
# 数据选取 一列
print(df['score'])
# 数据选取 多列
print(df[['num', 'score']])
# 按位置选取数据 第一行
print(df.iloc[0])
# 按索引选取数据 第一行
print(df.loc[0])
# 按位置选取数据 第一行
print(df.iloc[0,:])
# 按位置选取数据 第一行前三列
print(df.iloc[0,:3])
# 按位置选取数据 第一行第一列
print(df.iloc[0,0])
# 输出列名
print(df.columns)
# 导入数据
df = pd.read_csv('C:/Users/guojl/Desktop/example/data/score.txt')
# 修改列名
df.columns = ['a', 'b', 'c']
print(df.columns)
# 查看数据空值,返回 bool 逻辑值, True or False
print(df.isnull())
# 查看数据非空值,返回 bool 逻辑值, True or False
print(df.notnull())
# 删除所有包含空值的行
df.dropna()
print(df)
# 删除所有包含空值的列
df.dropna(axis=1)
print(df)
# axis 参数:0为行 1为列
# 保留至少有 3 个非空值的行
df.dropna(thresh=3)
# 用 x 替换数据中的所有空值
df.fillna('x')
# 数据类型更改为 float 类型
df.astype(float)
# replace 替换数据
df_str = '小明是一名学生,成绩优异'
df = df_str.replace('明', '雷')
print(df)
# replace 替换多个数据
df_str = '小明是一名学生,成绩优异'
df = df_str.replace('明', '雷').replace('成绩', '表现')
print(df)
# rename 更改列名
dic = [{'a':1, 'b':2},
{'c':3, 'd':4},
{'e':5, 'f':6}]
df = pd.DataFrame(dic)
df1 = df.rename(columns={'a':'one', 'b':'two', 'c':'three', 'd':'four', 'e':'five', 'f':'six'})
print(df1.columns)
# 选择性更改
df1 = df.rename(columns={'a':'one', 'b':'two'})
# 更改索引列
dic1 = {'class':[211, 212, 213,214, 215], 'num':[34, 33, 35, 36, 37],
'name':['小张', '小李', '小王', '小赵', '小郑']}
dic_dt = pd.DataFrame(dic1)
df = dic_dt.set_index('name')
print(df)
# 批量重命名索引
dic1 = {'class':[211, 212, 213,214, 215], 'num':[34, 33, 35, 36, 37],
'name':['小张', '小李', '小王', '小赵', '小郑']}
dic_dt = pd.DataFrame(dic1)
df = dic_dt.rename(index=lambda x: x+3)
print(df)
# 批量更改列名
dic1 = {1:[211, 212, 213,214, 215], 2:[34, 33, 35, 36, 37],
3:['小张', '小李', '小王', '小赵', '小郑']}
dic_dt = pd.DataFrame(dic1)
df = dic_dt.rename(columns=lambda x: x+3)
print(df)
# 选择 num 列大于 35 的行
dic1 = {'class':[211, 212, 213,214, 215], 'num':[34, 33, 35, 36, 37],
'name':['小张', '小李', '小王', '小赵', '小郑']}
dic_dt = pd.DataFrame(dic1)
df = dic_dt[dic_dt['num'] > 35]
print(df)
# 排序,按照 num 列排序, 默认升序
dic1 = {'class':[211, 212, 213,214, 215], 'num':[34, 33, 35, 36, 37],
'name':['小张', '小李', '小王', '小赵', '小郑']}
dic_dt = pd.DataFrame(dic1)
df = dic_dt.sort_values('num')
print(df)
# 降序
df = dic_dt.sort_values('num', ascending=False)
# 先按 num 降序, 再按 class 升序
df = dic_dt.sort_values(['num', 'class'], ascending=[False, True])
print(df)
# 返回一个按 num 列进行分组的 GroupBy 对象
dic1 = {'class':[211, 212, 211,214, 214], 'num':[34, 33, 33, 34, 37],
'name':['小张', '小李', '小王', '小赵', '小郑']}
dic_dt = pd.DataFrame(dic1)
df = dic_dt.groupby('num')
print(df)
# 返回一个按 class、num 列进行分组的 GroupBy 对象
dic1 = {'class':[211, 212, 211,214, 214], 'num':[34, 33, 33, 34, 37],
'name':['小张', '小李', '小王', '小赵', '小郑']}
dic_dt = pd.DataFrame(dic1)
df = dic_dt.groupby(['class','num'])
print(df)
# 返回一个按 class 分组后、num 列均值
dic1 = {'class':[211, 212, 211,214, 214], 'num':[34, 33, 33, 34, 37],
'name':['小张', '小李', '小王', '小赵', '小郑']}
dic_dt = pd.DataFrame(dic1)
df = dic_dt.groupby('class')['num']
print(df)
# 输出 df 中值
for key, value in df:
print(key)
print(value)
# 返回一个按 class 分组后,计算num, score 的最大值的数据透视表
dic1 = {'class':[211, 212, 211,214, 214], 'num':[34, 33, 33, 34, 37],
'name':['小张', '小李', '小王', '小赵', '小郑'], 'score':[100, 99, 99, 80, 89]}
dic_dt = pd.DataFrame(dic1)
df = dic_dt.pivot_table(index='class', values=['num','score'], aggfunc=max)
print(df)
# 返回按 class 列分组的所有列均值
dic1 = {'class':[211, 212, 211,214, 214], 'num':[34, 33, 33, 34, 37],
'name':['小张', '小李', '小王', '小赵', '小郑'], 'score':[100, 99, 99, 80, 89]}
dic_dt = pd.DataFrame(dic1)
df = dic_dt.groupby('class').agg(np.mean)
print(df)
# 对每一列求均值
dic1 = {'class':[211, 212, 211,214, 214], 'num':[34, 33, 33, 34, 37],
'score':[100, 99, 99, 80, 89]}
dic_dt = pd.DataFrame(dic1)
df = dic_dt.apply(np.mean)
print(df)
# 对每一行求均值
dic1 = {'class':[211, 212, 211,214, 214], 'num':[34, 33, 33, 34, 37],
'score':[100, 99, 99, 80, 89]}
dic_dt = pd.DataFrame(dic1)
df = dic_dt.apply(np.mean, axis=1)
print(df)
# 对每一列求最大值
dic1 = {'class':[211, 212, 211,214, 214], 'num':[34, 33, 33, 34, 37],
'score':[100, 99, 99, 80, 89]}
dic_dt = pd.DataFrame(dic1)
df = dic_dt.apply(np.max, axis=0)
print(df)
# 将 dic2 的行加入 dic_dt 尾部
dic1 = {'class':[211, 212, 211,214, 214], 'num':[34, 33, 33, 34, 37],
'score':[100, 99, 99, 80, 89]}
dic_dt = pd.DataFrame(dic1)
dic2 = dic_dt
df = dic_dt.append(dic2)
print(df)
# 将 dic2 的列加到 dic_dt 的尾部
dic1 = {'class':[211, 212, 211,214, 214], 'num':[34, 33, 33, 34, 37],
'score':[100, 99, 99, 80, 89]}
dic_dt = pd.DataFrame(dic1)
dic2 = dic_dt
df = pd.concat([dic_dt, dic2], axis= 1)
print(df)
# join 用法
lis = ['abc', 'xiaozhang', '大数据', '123']
df = '-'.join(lis)
print(df)
# 汇总统计
dic1 = {'class':[211, 212, 211,214, 214], 'num':[34, 33, 33, 34, 37],
'score':[100, 99, 99, 80, 89]}
dic_dt = pd.DataFrame(dic1)
df = dic_dt.describe()
print(df)
# 所有列的均值
df = dic_dt.mean()
# 列之间的相关系数
df = dic_dt.corr()
# 每一列的非空值个数
df = dic_dt.count()
# 每一列的最大值
df = dic_dt.max()
# 每一列的最小值
df = dic_dt.min()
# 每一列的中位数
df = dic_dt.median()
# 每一列的标准差
df = dic_dt.std()
QQ群文件“第4章 4 pandas实验.txt”
Jupyter Notebook是什么
Jupyter Notebook是一个开源的web应用程序,一个交互式笔记本,支持运行 40 多种编程语言。
它允许您创建和共享文档,包含代码,方程,可视化和叙事文本。
用途包括:数据清洗和转换,数值模拟,统计建模、数据可视化、机器学习等等。
支持以网页的形式分享,GitHub 中天然支持 Notebook 展示,也可以通过 nbviewer 分享你的文档。当然也支持导出成 HTML、Markdown 、PDF 等多种格式的文档。
不仅可以输出图片、视频、数学公式,甚至可以呈现一些互动的可视化内容,比如可以缩放的地图或者是可以旋转的三维模型。
通过 pip 安装:pip install jupyter
安装成功提示有:jupyter、jupyter-client、jupyter-console、jupyter-core。
打开打开cmd命令提示符窗口输入jupyter notebook 回车,然后浏览器就会打开Jupyter notebook。
import pandas as pd
student = pd.read_table('C:\\Users\\guojl\\Desktop\\students.txt', sep = ',')
print(student)
student[student['age']>23]
student[student['age']>22]
student.groupby('class')['id'].count().reset_index().rename(columns={'id':'count'})
student.groupby('class')['age'].min().reset_index().rename(columns = {'age':'min_age'})
score = pd.read_table('C:\\Users\\guojl\\Desktop\\score.txt', sep = ',')
print(score)
score.columns
score.groupby("id")["score"].sum().reset_index().rename(columns={'score':'sum_score'}).sort_values('sum_score', ascending = False).head()
student.merge(score, on = 'id')
merge(left, right, how=‘inner’, on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=(’_x’, ‘_y’), copy=True, indicator=False, validate=None)
left 参与合并的左侧DataFrame
right 参与合并的右侧DataFrame
how 连接方式:‘inner’(默认)、‘outer’、‘left’、‘right’,分别对应内连接、外连接、左连接、右连接;外连接其实左连接和右连接的并集。左连接是左侧DataFrame取全部数据,右侧DataFrame匹配左侧DataFrame。(右连接right和左连接类似)
on 用于连接的列名,必须同时存在于左右两个DataFrame对象中,如果未指定,则以left和right列名的交集作为连接键
left_on 左侧DataFarme中用作连接键的列
right_on 右侧DataFarme中用作连接键的列
left_index 将左侧的行索引用作其连接键
right_index 将右侧的行索引用作其连接键
sort 根据连接键对合并后的数据进行排序,默认为True。有时在处理大数据集时,禁用该选项可获得更好的性能
suffixes 字符串值元组,用于追加到重叠列名的末尾,默认为(‘_x’,‘_y’).例如,左右两个DataFrame对象都有‘data’,则结果中就会出现‘data_x’,‘data_y’
copy 设置为False,可以在某些特殊情况下避免将数据复制到结果数据结构中。默认总是赋值
作用:
连接两个DataFrame并返回连接之后的DataFrame
import matplotlib.pyplot as plt
df = student.groupby('class')['id'].count().reset_index().rename(columns={'id':'count'})
plt.rcParams['font.family']=['SimHei']
fig,ax = plt.subplots()
ax.plot(df['class'], df['count'])
ax.set_xticklabels(labels=df['class'], rotation=90) # 旋转90度
plt.show()