【Python 数据分析学习】Pandas的基础和应用(2)

题目

  • [1 数据运算与分析](#1 数据运算与分析)
    • [1.1 算数和比较运算](#1.1 算数和比较运算)
      • [1.1.1 算数运算](#1.1.1 算数运算)
      • [1.1.2 比较运算](#1.1.2 比较运算)
    • [1.2 数据排列](#1.2 数据排列)
    • [1.3 统计分析](#1.3 统计分析)
      • [1.3.1 基本的统计分析函数](#1.3.1 基本的统计分析函数)
      • [1.3.2 特殊的统计分析函数](#1.3.2 特殊的统计分析函数)
      • [1.3.3 检查和处理空值](#1.3.3 检查和处理空值)
    • [1.4 分组与聚合](#1.4 分组与聚合)
      • [1.4.1 数据分组](#1.4.1 数据分组)
      • [1.4.2 数据聚合](#1.4.2 数据聚合)
    • [1.5 透视交叉表](#1.5 透视交叉表)
      • [1.5.1 透视表](#1.5.1 透视表)
      • [1.5.2 交叉表](#1.5.2 交叉表)
  • [2 实战演练](#2 实战演练)
    • [2.1 实战 1](#2.1 实战 1)

1 数据运算与分析

1.1 算数和比较运算

1.1.1 算数运算

Pandas为Series和DataFrame提供了许多算术运算 的方法,算术规则是根据行列索引补齐后进行运算,运算结果默认为浮点型,补齐时缺项填充为NaN。

四则运算时:返回一个新的对象,也可以采用相关方法,实现相似的效果,分别是:

.add(d,**argws)

.sub(d,**argws)

.mul(d,**argws)

.div(d,**argws)

  1. 四则运算:索引一样且都为整型。

代码演示:

python 复制代码
df1 = pd.DataFrame([np.arange(0,4),np.arange(1,5),np.arange(2,6)])
df2 = pd.DataFrame([np.arange(1,5),np.arange(0,4),np.arange(3,7)])
print("df1:\n",df1)
print("df2:\n",df2)
print("df1+df2:\n",df1+df2)
  1. 四则运算:索引不一样

代码演示:

python 复制代码
df1 = pd.DataFrame([np.arange(0,4),np.arange(1,5),np.arange(2,6),np.arange(2,6)])
df2 = pd.DataFrame([np.arange(1,5),np.arange(0,4),np.arange(3,7)])
print("df1:\n",df1)
print("df2:\n",df2)
print("df1+df2:\n",df1+df2)
  1. 四则运算,运算DataFrame中的指定的列

代码演示:

python 复制代码
df1  = pd.DataFrame(data = {"score": [80,70,60,50], "name1": ["小明", "小红", "小刚", "小华"]})
df2  = pd.DataFrame(data = {"score": [70,60,50,40], "name2": ["李明", "李华", "张兵", "王军"]})
print("df1:\n",df1)
print("df2:\n",df2)
print('df1["score"] - df2["score"]:\n',df1["score"] - df2["score"])

1.1.2 比较运算

比较运算:只能比较相同索引的元素,而且不进行补齐操作,返回一个布尔型的对象。常见的比较运算有:'>','<','>=','<=','==','!='等。

  1. 索引一样,比较全部
    代码演示:
python 复制代码
df1 = pd.DataFrame([np.arange(0,4),np.arange(1,5),np.arange(2,6)])
df2 = pd.DataFrame([np.arange(1,5),np.arange(0,4),np.arange(3,7)])
print("df1:\n",df1)
print("df2:\n",df2)
print("df1>df2:\n",df1>df2)
  1. 索引一样,比较DataFrame中指定的列

代码演示:

python 复制代码
df1  = pd.DataFrame(data = {"score": [80,70,60,50], "name1": ["小明", "小红", "小刚", "小华"]})
df2  = pd.DataFrame(data = {"score": [70,60,50,40], "name2": ["李明", "李华", "张兵", "王军"]})

print(df1["score"]>df2["score"])

1.2 数据排列

Pandas提供了数据排序的方法,既可以依据行列 的索引排序,也可以依据指定行列索引的数据排序。排序主要利用的方法是sort_index()和sort_values()。

  1. 依据索引排序 :采用sort_index(axis=[0,1],ascending=True)方法。通过设置参数axis 实现对行索引和列索引的排序,一般默认升序。
    当axis=1时,实现对列索引的排序;
    当axis=0时,实现对行索引的排序。

代码演示:

python 复制代码
arr = np.arange(12).reshape(3,4)
df = pd.DataFrame(data=arr, index = ["a",'b','c'], columns= ["a","b","c","d"])
df.sort_index(axis = 1) #列排序
print("df.sort_index(axis = 1):\n", df)
  1. 依据数值排序:使用的方法是sort_values(by,axis=0,ascending=True),其中默认升序,by是axis轴上的某个索引或者索引列表。此外,若含有空值时,统一排序到末尾。

代码演示:

python 复制代码
df1  = pd.DataFrame(data = {"score": [80,70,60,50], "name1": ["小明", "小红", "小刚", "小华"]})
df2  = pd.DataFrame(data = {"score": [70,60,50,40], "name2": ["李明", "李华", "张兵", "王军"]})

df = df1.sort_values(by = "score",ascending = False)
print("score这一列排序,降序:\n",df)

1.3 统计分析

1.3.1 基本的统计分析函数

Pandas提供的Series和DataFrame两种数组类型还支持各种统计分析的操作。基本的统计分析函数一般均适用于以上两种数据类型。常见的基本统计函数如下表。

  1. **describe()**方法返回的结果包括各列的元素个数、均值、标准差、最小值、四分之一分位点、中位数、四分之三分位点和最大值。

代码演示:

python 复制代码
df1  = pd.DataFrame(data = {"score": [80,70,60,50], "name": ["小明", "小红", "小刚", "小华"]})
df2  = pd.DataFrame(data = {"score": [70,60,50,40], "name": ["李明", "李华", "张兵", "王军"]})

#合并
df = pd.concat([df1, df2])
print(df)
#单独打印最大值
print("score 的最大值:",df["score"].sum())

#针对各列的统计汇总
print("针对各列的统计汇总: \n",df.describe())
  1. **corr()**方法可以返回数值列或指定两个数值列之间的相关系数。

代码演示:

python 复制代码
df1  = pd.DataFrame(data = {"score1": [80,70,60,50],"score2": [70,90,50,40], "name": ["小明", "小红", "小刚", "小华"]})
df2  = pd.DataFrame(data = {"score1": [70,60,50,40], "score2": [80,70,90,50],"name": ["李明", "李华", "张兵", "王军"]})

#合并
df = pd.concat([df1,df2])
#使用corr函数
print("corr函数:\n",df["score1"].corr(df["score2"]))

1.3.2 特殊的统计分析函数

对于Pandas数据,由于其类似表格的特性,还支持许多累计统计的分析,为数据分析提供了很大的方便,也成Pandas的一大优势。常见的累计统计分析函数如下表。

  1. .cumsum()和.cumprod()函数分别返回一个DataFrame,除第一数据外,其余行是前几行(包括本行)数据累加/积的结果。本例中,df.cumsum()和df.cumprod()的结果如下:
python 复制代码
arr = np.arange(12).reshape(4,3)
df = pd.DataFrame(data = arr)
print(df)
print("")
print("df.cumsum():\n",df.cumsum())
print("")
print("df.cumprod():\n",df.cumprod())
  1. .cummax()和.cummin()函数分别返回一个DataFrame,返回值分别为对应列上前几行数据的最大值和最小值。本例中,df.cummax()和df.cummin()的结果如下:

代码演示:

python 复制代码
arr = np.arange(12).reshape(4,3)
df = pd.DataFrame(data = arr)
print(df)
print("")
##最大值
print("df.cummax():\n",df.cummax())
print("")

#最小值
print("df.cummin():\n",df.cummin())
  1. 此外,Pandas在统计操作中,还支持滚动计算,利用的函数主要是.rollong(w).sum()等类似函数,其中,w主要是指参与运算的元素数量,其返回值是一个DataFrame,缺失值以NaN补全,df.rolling(2).sum()的结果下:

代码演示:

python 复制代码
arr = np.arange(12).reshape(4,3)
df = pd.DataFrame(data = arr)
print(df)
print("")
print(df.rolling(2).sum())

1.3.3 检查和处理空值

  1. 要检查Pandas DataFrame中是否存在空值,你可以使用 .isnull() 方法结合 .sum() 方法来统计每一列中的空值数量。这里有一个步骤说明如何操作:
    (1)使用.isnull()方法来创建一个布尔DataFrame,其中True表示缺失值,False表示非缺失值。
    (2)对于每个列,使用.sum()方法来计算有多少个True(即缺失值的数量)。
    (3)如果想检查整个DataFrame是否有任何缺失值,可以检查.isnull().sum().sum()的结果是否大于零。

代码演示:

python 复制代码
data = {
    "name":["小李","小红","小明","小刚"],
    "age":[18,None,18,20],
    "class":[None,2,None,3]
}
#创建一个DataFrame
df = pd.DataFrame(data)
print(df)
print(".isnull(), 以表格形式打印空值 :\n",df.isnull())
print(".isnull().sum() 统计每行的空值的个数:\n", df.isnull().sum())
print(".isnull().sum().sum() 统计全部的空值的个数:\n", df.isnull().sum().sum())
  1. (1)你可以选择用一个固定的值来填充所有的空值,比如0或者某个特定的字符串。
    (2)ffill (前向填充) 或者 bfill (后向填充) 可以用来用前一个或后一个有效值来填充空值。
    (3)可以用某一列的平均值、中位数或众数来填充空值。

代码演示:

python 复制代码
data = {
    "name":["小李","小红","小明","小刚"],
    "age":[18,None,18,20],
    "class":[None,2,None,3]
}
#创建一个DataFrame
df = pd.DataFrame(data)
print(df)
# df1 = df.fillna(0,inplace=True) #这里的inplace参数会直接改变原df的值
df1 = df.fillna(0)
print(".fillna(0), 把全部空值填为0:\n" ,df1)
df2 = df.ffill()
print("ffill(), 用前一行对应的数值填充:\n",df2)

1.4 分组与聚合

1.4.1 数据分组

可以使用groupby()根据索引或字段对数据进行分组,具体的用法如下所示:
DataFrame.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=<no_default>, observed=False, dropna=True)

说明如下:

groupby分组后的结果不再是DataFrame类型,而是一个DataFrameGroupBy对象。可以按单列分组,也可以同时按多个列进行分组,如df.groupby(["A", "B"])表示按A和B两列进行分组。

代码演示:

python 复制代码
data = {'A':["数学", "语文","数学", "英语","数学", "语文","英语"],
        'B':[2001,2003,2005,2003,2001,2005,2004],
        'C':np.arange(7,14)}
df = pd.DataFrame(data = data)
A_group = df.groupby("A")
print(type(A_group))

1.4.2 数据聚合

分组后的结果不能直接查看,可以使用聚合运算对分组后数据进行计算,并查看可聚合计算后的结果,常用的数据聚合方法如下表所示:

单个分组,代码演示:

python 复制代码
data = {'A':["数学", "语文","数学", "英语","数学", "语文","英语"],
        'B':[2001,2003,2005,2003,2001,2005,2004],
        'C':np.arange(7,14)}
df = pd.DataFrame(data = data)
## 把A分组
A_group = df.groupby("A")
print("使用A的分组, A_group.sum():\n",A_group.count())
## 把B分组
B_group = df.groupby("B")
print("使用B的分组, B_group.sum():\n",B_group.count())

同时多个分组,代码演示:

python 复制代码
data = {'A':["数学", "语文","数学", "英语","数学", "语文","英语"],
        'B':[2001,2003,2005,2003,2001,2005,2004],
        'C':np.arange(7,14)}
df = pd.DataFrame(data = data)
## 把A和B同时分组
AB_group = df.groupby(["A","B"])
print("使用AB的分组, AB_group.sum():\n",AB_group.count())

1.5 透视交叉表

1.5.1 透视表

数据透视表是常用的数据分析工具之一,它可以根据一个或多个指定的维度对数据进行聚合。在python中可以通过pandas.pivot_table函数来实现数据透视表。pandas.pivot_table函数包含5个主要参数及其他可选参数,如下所示:
pandas.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All', observed=False, sort=True)

说明如下:

这里我们用df. pivot_table()演示:

  1. 设置一个学校成绩表,里面包含了每人的成绩和班级。假设我们想得到每个班级的最高分和平均分

代码演示:

python 复制代码
## 设置一个学校成绩表,里面包含了每人的成绩和班级
data = {
        "score":[93,95,92,91,96,98],
        "name":["小明","小华","小红","小东","小刚","小强"],
        "class":[3,2,1,1,2,1],
}

#sort_values("score",ascending = False) 把分数按降序排序
#reset_index(drop = True)  把索引设置为0可是的升序
df = pd.DataFrame(data= data).sort_values("score",ascending = False).reset_index(drop = True)
print(df)

#班级作为行进行聚合,列为score,aggafun默认是平均值: 打印每班级的平均值
p1 = df.pivot_table(["score"],index = ["class"])
print('班级作为行进行聚合,列为score,aggafun默认是平均值:\n',p1)

#班级作为行进行聚合,列为score,aggafun= max: 打印每班级的最大值
p2 = df.pivot_table(["score"],index = ["class"],aggfunc = "max")
print('班级作为行进行聚合,列为score,aggafun= max:\n',p2)
  1. 假设我们想得到每个班级的人和分数,可以设置 班级姓名 为行索引

代码演示:

python 复制代码
## 设置一个学校成绩表,里面包含了每人的成绩和班级
data = {
        "score":[93,95,92,91,96,98],
        "name":["小明","小华","小红","小东","小刚","小强"],
        "class":[3,2,1,1,2,1],
}

# sort_values("score1",ascending = False) 把分数按降序排序
# reset_index(drop = True)  把索引设置为0可是的升序
df = pd.DataFrame(data= data).sort_values("score",ascending = False).reset_index(drop = True)
print(df)

#班级和姓名作为行进行聚合,列为score,aggafun默认: 打每班级各个人集合在一起,并打印每人的成绩
p2 = df.pivot_table(["score"],index = ["class","name"])
print('班级和姓名作为行进行聚合,列为score,aggafun默认:\n',p2)
  1. 同时设置对列的操作,这里设置对score求最大值和平均值。

代码演示:

python 复制代码
## 设置一个学校成绩表,里面包含了每人的成绩和班级
data = {
        "score1":[93,95,92,91,96,98],
        "score2":[93,9,92,91,96,98],
        "name":["小明","小华","小红","小东","小刚","小强"],
        "class":[3,2,1,1,2,1],
}

#sort_values("score1",ascending = False) 把分数按降序排序
#reset_index(drop = True)  把索引设置为0可是的升序
df = pd.DataFrame(data= data).sort_values("score1",ascending = False).reset_index(drop = True)
print(df)

# #班级作为行进行聚合,列为score,aggafun= {"score1": "max","score2": "mean"}: 同时打印每班级的最大值和平均值
p3 = df.pivot_table(["score1","score2"],index = ["class"],aggfunc ={"score1": "max","score2": "mean"})
print('班级作为行进行聚合,列为score,aggafun={"score1": "max","score": "mean"}:\n',p3)

1.5.2 交叉表

交叉表是一种特殊的透视表,主要用于计算分组频率。pandas. crosstab 函数可以用于制作交叉表,该函数的参数和使用格式如下。
pandas.crosstab(index, columns, values=None, rownames=None, colnames=None, aggfunc=None, margins=False, margins_name='All', dropna=True, normalize=False)

  1. 设置一个学校成绩表,里面包含了每人的成绩和班级。在每个班级中各个分数段有多少人

代码演示:

python 复制代码
## 设置一个学校成绩表,里面包含了每人的成绩和班级
data = {
        "score":[93,95,92,91,95,98],
        "name":["小明","小华","小红","小东","小刚","小强"],
        "class":[3,2,1,1,2,1],
}

# sort_values("score1",ascending = False) 把分数按降序排序
# reset_index(drop = True)  把索引设置为0可是的升序
df = pd.DataFrame(data= data).sort_values("score",ascending = False).reset_index(drop = True)
print(df)
print("")
# 在每个班级中各个分数段有多少人
p = pd.crosstab(index = df["class"], columns =df["score"])
print("在每个班级中各个分数段有多少人:\n",p)
  1. 设置一个学校成绩表,里面包含了每人的成绩和班级。在每个班级中各个分数段有多少人,可以使用normalize参数对频率表进行规范化,以显示百分比,而不是计数。另外,还可以将margins参数设置为True,则可以打开汇总(Total)功能。

代码演示:

python 复制代码
## 设置一个学校成绩表,里面包含了每人的成绩和班级
data = {
        "score":[93,95,92,91,95,98],
        "name":["小明","小华","小红","小东","小刚","小强"],
        "class":[3,2,1,1,2,1],
}

# sort_values("score1",ascending = False) 把分数按降序排序
# reset_index(drop = True)  把索引设置为0可是的升序
df = pd.DataFrame(data= data).sort_values("score",ascending = False).reset_index(drop = True)
print(df)
print("")
# 在每个班级中各个分数段占的百分比
p = pd.crosstab(index = df["class"], columns =df["score"],normalize = True, margins = True)
print("normalize = True,margins = True;在每个班级中各个分数段有多少人:\n",p)

2 实战演练

2.1 实战 1

  1. 先生成一个数据存入文件

代码演示:

python 复制代码
# 设置随机种子以保证结果可复现
np.random.seed(0)

# 定义数据列和行数
columns = ['ID', 'Name', 'Age', 'Height', 'City']
n_rows = 1000  # 假设我们想要生成1000行数据

# 生成一些示例数据
data = {
    'ID': range(1, n_rows + 1),
    'Name': [f'Person_{i}' for i in range(n_rows)], #把人名设置为 Person_**  的形式
    'Age': np.random.randint(18, 60, size=n_rows), #创建年龄,size参数设置数组元素个数
    'Height': np.random.randint(170, 191, size= n_rows),  # 身高170-190, size参数设置数组元素个数
    'City': np.random.choice(['Beijing', 'Shanghai', 'Guangzhou', 'Shenzhen'],size=n_rows) # 随机城市已被限定
}

# 创建DataFrame
df = pd.DataFrame(data)

#DataFrame对象存入文本文件
df.to_csv("test_1.txt", index = False)
print("存入成功")
  1. 从文件读取数据

代码演示:

python 复制代码
##读取数据
df = pd.read_csv("D:/Python_Pycharm/Code/Python_Code/论文_1/数据分析资料包/test_1.txt")
print("读取成功")
print(df)
  1. 检查数据是否有空值
    代码演示:
python 复制代码
#检查数据共有多少空值
print("数据的空值个数:", df.isnull().sum().sum())
  1. 查找身高的最大值和最小值的个人信息

代码演示:

python 复制代码
# 找出身高最大值和最小值
Height_max = df["Height"].max()
Height_min = df["Height"].min()

# 提取所有身高最大值的行
#根据身高列的最大值和最小值筛选出满足条件的所有行记录。
Height_max_rows = df[df["Height"]==Height_max ]
Height_min_rows = df[df["Height"]==Height_min ]

print("所有身高最大值的行:\n",Height_max_rows)
print("所有身高最小值的行:\n",Height_min_rows)


  1. 得到最大值和最小值的总数

代码演示:

python 复制代码
# 找出身高最大值和最小值
Height_max = df["Height"].max()
Height_min = df["Height"].min()

# 使用了布尔索引 (df['Height'] == max_height) 来生成一个布尔Series,对该Series求和
Height_max_sum = (df["Height"]== Height_max).sum()
Height_min_sum = (df["Height"]== Height_min).sum()

print("身高最大值的总数:", Height_max_sum)
print("身高最小值的总数:", Height_min_sum)
  1. 把数据以升高为参照排序

代码演示:

python 复制代码
# 把数据以身高为参照

#降序
sort1 = df["Height"].sort_values(ascending = False)
print("把数据以身高为参照,排降序:\n",sort1)

#升序
#sort2 = df["Height"].sort_values(ascending = True)
sort2 = df["Height"].sort_values() # 参数默认为ascending = True
print("把数据以身高为参照,排升序:\n",sort2)
  1. 聚合地区可以查看每个地区的人数;聚合身高可以查看每个身高的人数

代码演示:

python 复制代码
## 1.4 聚合地区可以查看每个地区的人数;聚合身高可以查看每个身高的人数

region1 = df.groupby("City")
print("集合地区,查看每个地区的人数:\n",region1.count())

region2 = df.groupby("Height")
print("聚合身高,可以查看每个身高的人数:\n",region2.count())


  1. 透视表

代码演示:

python 复制代码
# index = ["City"] 城市设置为索引
# values = ["Height","Age"]  身高和年龄设为列组
# aggfunc = "mean"  把身高和年龄的聚合设置为平均数

pivot_tab = df.pivot_table(values = ["Height","Age"], index = ["City"], aggfunc = "mean")
print("透视表:\n", pivot_tab)
相关推荐
databook14 分钟前
Manim实现闪光轨迹特效
后端·python·动效
Juchecar1 小时前
解惑:NumPy 中 ndarray.ndim 到底是什么?
python
用户8356290780512 小时前
Python 删除 Excel 工作表中的空白行列
后端·python
Json_2 小时前
使用python-fastApi框架开发一个学校宿舍管理系统-前后端分离项目
后端·python·fastapi
RestCloud2 小时前
数据传输中的三大难题,ETL 平台是如何解决的?
数据分析·api
数据智能老司机8 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机9 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机9 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机9 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i10 小时前
drf初步梳理
python·django