Pandas
(一)、Pandas基础知识
- 包括如何装载数据、查看数据集的行和列、分组、可视化统计数据
1、数据集的装载与基础操作
- 在分析数据之前,先要装载数据,以为为了提高数据分析效率,分析数据都是在内存中完成的。使用csv格式文件,需要使用
pandas
模块中的read_csv
函数装载这样本文件,并使用sep
关键字参数指定分隔符,如:“\t”, “,” 等 - 如果成功装载数据,
read_csv
函数会返回一个DataFrame
对象,该对象提供了很多方法和属性,可以完成很多操作,通过head
方法可以获取前5行的数据,通过columns
属性可以获得样本数据的列 - 例子:使用
read_csv
函数装载demo1.csv
文件,并输出样本数据的前5行,然后输出这二维数据集的记录数和列数,最后获取数据集的列信息
- demo1.csv数据如下:
id,name,age,sex,class
1,Joy Won,22,男,1
2,小明,20,男,2
3,小红,23,女,3
4,小梅,26,女,4
import pandas as pd
# 装载demo1.csv文件
df = pd.read_csv('./data/demo1.csv', sep=',')
# 输出数据
print(df)
print("-------------------------------")
# 查看数据类型
print(type(df))
print("-------------------------------")
# 获取前3行数据
print(df.head(3))
print("-------------------------------")
# 获取二维表的维度(行和列)
print(df.shape)
print("-------------------------------")
# 获取数据集的列
print(df.columns)
print("-------------------------------")
# 对数据集的列就行迭代
for i in df.columns:
print(i, end = " ")
id name age sex class
0 1 Joy Won 22 男 1
1 2 小明 20 男 2
2 3 小红 23 女 3
3 4 小梅 26 女 4
-------------------------------
<class 'pandas.core.frame.DataFrame'>
-------------------------------
id name age sex class
0 1 Joy Won 22 男 1
1 2 小明 20 男 2
2 3 小红 23 女 3
-------------------------------
(4, 5)
-------------------------------
Index(['id', 'name', 'age', 'sex', 'class'], dtype='object')
-------------------------------
id name age sex class
2、查看数据集的列
- 通过
DataFrame
对象可以非常容易的获取数据集指定列的数据 - 获取的方法与从字典中通过
key
检索value
类似。假设df
是DataFrame
类的实例,df['a']
就可以获取名为a的列的所有数据。如果只获取一列的数据,可以使用df['a']
,也可以使用df[['a']]
形式。前者返回的是Series
对象,后者返回的是DataFrame
对象。 Series
对象可以看作Python语言中的列表。也就是说,如果只要返回一列数据,可以是列表形式(Series),也可以是数据集形式(DataFrame)- 如果要返回多列的数据,必须使用
df[['a']]
形式。例如获取a和b两列数据,需要使用df[['a', 'b']]
形式获取,返回的是DataFrame
对象 - 例子:获取数据集1列和3列数据,前者返回
Series
对象,后者返回DataFrame
对象
import pandas as pd
df = pd.read_csv("./data/demo1.csv", sep = ',')
# 获取id列的数据,返回Series对象
id_df = df['id']
print(id_df)
print("---------------------")
# 获取id_df前2行数据
print(id_df.head(2))
print("---------------------")
# 获取id_df后2行数据
print(id_df.tail(2))
print("---------------------")
# 获取name、age、sex列的数据,返回DataFrame对象
subset = df[['name', 'age', 'sex']]
# 获取子集前2行数据
print(subset.head(2))
print("---------------------")
# 获取子集后2行数据
print(subset.tail(2))
0 1
1 2
2 3
3 4
Name: id, dtype: int64
---------------------
0 1
1 2
Name: id, dtype: int64
---------------------
2 3
3 4
Name: id, dtype: int64
---------------------
name age sex
0 Joy Won 22 男
1 小明 20 男
---------------------
name age sex
2 小红 23 女
3 小梅 26 女
3、查看数据集的行
- 查看数据集的行有两个方法:
loc
和iloc
。这两个方法的功能相同,只是获取行的方式不同 loc
通过记录集的索引列获取行,索引从0开始,不能为负数iloc
获取行的方法与Python语言的列表相同。可以用正索引,也可以用负索引(从-1开始)- 例子:通过
loc
方法获取数据集的第1行数据,然后使用loc
方法获取第2、3、4行数据,最后使用iloc
方法获取最后一行数据
import pandas as pd
df = pd.read_csv("./data/demo1.csv", sep = ",")
# 输出第1行数据
print(df.loc[0])
print("----------------------------")
# 输出第2、3、4行数据
print(df.loc[[1, 2, 3]])
print("----------------------------")
# 输出最后一行数据
print(df.iloc[-1])
print("----------------------------")
id 1
name Joy Won
age 22
sex 男
class 1
Name: 0, dtype: object
----------------------------
id name age sex class
1 2 小明 20 男 2
2 3 小红 23 女 3
3 4 小梅 26 女 4
----------------------------
id 4
name 小梅
age 26
sex 女
class 4
Name: 3, dtype: object
----------------------------
4、查看数据集单元格中的数据
- 如果在获取数据集的子数据集时,同时指定行和列,那么会解决数据集中间的一块数据,甚至可以获取某个单元格中的数据
loc
方法与iloc
方法都可以实现这个功能。- 如果使用
loc
方法,例如:df.loc[1, 'a']
同时指定了行和列,获取第2行,列名为a的单元格中的数据。 - 如果使用
iloc
方法,列要使用索引,例如:df.iloc[0:3, 2:4]
指定了索引为0、1、2的行和索引为1、3的列,共3行2列6个单元格的数据 - 例子:
import pandas as pd
df = pd.read_csv("./data/demo1.csv", sep = ",")
# 获取name列和age列的所有数据
subset = df.loc[:, ['name', 'age']]
print(subset)
print("----------------------------")
# 获取索引为2、3、-1(最后一列)的列的所有数据
subset = df.iloc[:, [2, 3, -1]]
print(subset)
print("----------------------------")
# 获取索引为2、3、4的列的所有数据
subset = df.iloc[:, 2:5]
print(subset)
print("----------------------------")
# 获取行索引为0、1、2,列索引为1、2、3的数据
subset = df.iloc[0:3, 1:4]
print(subset)
print("----------------------------")
# 获取行索引为1,列名为name的数据
subset = df.loc[1, "name"]
print(subset)
print("----------------------------")
name age
0 Joy Won 22
1 小明 20
2 小红 23
3 小梅 26
----------------------------
age sex class
0 22 男 1
1 20 男 2
2 23 女 3
3 26 女 4
----------------------------
age sex class
0 22 男 1
1 20 男 2
2 23 女 3
3 26 女 4
----------------------------
name age sex
0 Joy Won 22 男
1 小明 20 男
2 小红 23 女
----------------------------
小明
----------------------------
5、对数据集进行分组统计
- 对一个数据集进行分组是数据分析经常要做的工作,例如要得到男女年龄得平均值,就要对性别列进行分组,然后对年龄取平均值。
- 对数据集分组使用
groupby
方法,计算某一列得平均值用mean
方法
# 对sex列分组,然后在组内对age列计算平均值
df.groupby('sex')['age'].mean()
- 使用
nunique
方法可以计算分组后某个列得不同值得个数
# 按sex列分组后,统计每一个sex含有多少人
df.groupby('sex')['name'].nunique()
- 例子:
import pandas as pd
df = pd.read_csv("./data/demo1.csv", sep = ",")
# 单列分组统计
print(df.groupby('sex')['age'].mean())
print("-----------------------------")
print(df.groupby('sex')['name'].nunique())
print("-----------------------------")
# 多列分组统计(先根据sex分组,然后再根据name二次分组,然后计算同名的平均年龄)
result = df.groupby(['sex', 'name'])['age'].mean().head(2)
print(result)
print("-----------------------------")
# 重置索引,让每一个行都显示行索引(从0开始)
print(result.reset_index())
print("-----------------------------")
sex
女 24.5
男 21.0
Name: age, dtype: float64
-----------------------------
sex
女 2
男 2
Name: name, dtype: int64
-----------------------------
sex name
女 小梅 26.0
小红 23.0
Name: age, dtype: float64
-----------------------------
sex name age
0 女 小梅 26.0
1 女 小红 23.0
-----------------------------
6、可视化统计数据
-
demo6.csv 如下:
id,name,age,sex,city 1,asd,10,男,1 2,asdfa,20,女,2 3,ffgsg,33,男,3 4,dfg,12,女,2 5,dfas,32,女,2 6,fghj,21,女,3 7,ghdf,45,女,1 8,gvcad,45,女,2 9,vafga,32,男,3 10,sfgsdh,23,男,2 11,aff,12,男,3 12,gafdg,23,男,1 13,gfdg,54,男,1 14,afvaf,65,男,2 15,fgadfg,54,女,3 16,fgafv,34,女,2 17,vafga,23,男,1 18,vadf,23,男,3 19,asd,10,男,1 20,asdfa,20,女,2 21,ffgsg,33,男,3 22,dfg,12,女,2 23,dfas,32,女,2 24,fghj,21,女,3 25,ghdf,45,女,1 26,gvcad,45,女,2 27,vafga,32,男,3 28,sfgsdh,23,男,2 29,sfgsdh,23,男,2 30,aff,12,男,3 31,gafdg,23,男,1
-
例子:
import pandas as pd import matplotlib.pyplot as plt df = pd.read_csv("./data/demo6.csv", sep = ",") plt.rcParams["font.sans-serif"] = ["SimHei"] # 设置字体 # 统计每个城市样本的平均年龄 age = df.groupby("city")["age"].mean() print(age) boyAge = df.groupby(['sex'])['age'].mean() print(boyAge) # 创建绘画板 fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4)) # ax1绘入图像 ax1.plot(age) ax2.plot(boyAge) plt.show()
(二)、Pandas数据类型
Pandas中两个重要的数据类型:Series
和DataFrame
,Series
表示数据列表,DataFrame
表示二维数据集
1、创建Series
-
Series
对象其实就是对一个序列的封装,相当于Python语言中的列表。Series
对象不仅可以在数据分析过程中获取,还可以单独创建。可以通过传给Series
类的构造方法一个列表的反式创建Series
对象 -
pd.Series([1, 2, 3, 4])
-
例子:通过列表创建多个Series对象。这些Series对象中的值有的是同一个数据类型,有的是不同数据类型
import pandas as pd # 创建整数类型的Series对象 s1 = pd.Series([1, 2, 3, 4]) print(s1) print("--------end---------") # 创建整数和浮点数混合类型的Series对象 s2 = pd.Series([1, 2.3, 4.5]) print(s2) print("--------end---------") # 创建布尔类型的Series对象 s3 = pd.Series([False, True]) print(s3) print("--------end---------") # 创建混合类型的Series对象 s4 = pd.Series([1, 2, 3.4, True, "hello"]) print(s4) print("--------end---------") # 改变第一列的索引(默认是数字) s5 = pd.Series(['joy won', 22], index = ['name', 'age']) print(s5) print("--------end---------")
0 1 1 2 2 3 3 4 dtype: int64 --------end--------- 0 1.0 1 2.3 2 4.5 dtype: float64 --------end--------- 0 False 1 True dtype: bool --------end--------- 0 1 1 2 2 3.4 3 True 4 hello dtype: object --------end--------- name joy won age 22 dtype: object --------end---------
2、创建DataFrame
-
DataFrame
相当于二维数据表,向DataFrame
类构造方法传入一个字典可以手动创建一个DataFrame
对象,字典每一个key
对应一列,与key
对应value
是一个列表类型的值,表示该列下的所有数据。同时还可以使用columns
关键字参数指定列的顺序,通过index
关键字参数改变默认的索引值。 -
例子:创建两个
DataFrame
对象,其中第二个DataFrame
对象中创建时使用columns
和index
关键字参数import pandas as pd # 创建第一个DataFrame对象 df1 = pd.DataFrame( { 'name': ['joy won', 'joy', 'won'], 'age': [10, 20, 30], 'class': [1, 2, 3], 'id': ["2001", "2001", "2003"] } ) print(df1) print("---------------end----------------") df2 = pd.DataFrame( { 'name': ['joy won', 'joy', 'won'], 'age': [10, 20, 30], 'class': [1, 2, 3], 'id': ["2001", "2001", "2003"] }, # 更换列的数据输出顺序 columns = ['id', 'class', 'name', 'age'], index = ['joywon', 'joy', 'won'] ) print(df2) print("---------------end----------------")
name age class id 0 joy won 10 1 2001 1 joy 20 2 2001 2 won 30 3 2003 ---------------end---------------- id class name age joywon 2001 1 joy won 10 joy 2001 2 joy 20 won 2003 3 won 30 ---------------end----------------
3、Series的基本操作
-
Series对象支持很多操作。例如,获取索引、数据值。
-
例子:从数据集中获取一行数据,并创建一个
Series
对象,然后获取Index
和Value
import pandas as pd df1 = pd.DataFrame( { 'name': ['joy won', 'joy', 'won'], 'age': [10, 20, 30], 'class': [1, 2, 3], 'id': ["2001", "2001", "2003"] }, # 更换列的数据输出顺序 columns = ['id', 'class', 'name', 'age'], index = ['joywon', 'joy', 'won'] ) print(df1) print("----------------end----------------\n") # 获取索引为 joywon 的整行数据 first_data = df1.loc['joywon'] print(first_data) print("----------------end----------------\n") # 获取列名 index_data = first_data.index print(index_data) print(index_data[0]) print("----------------end----------------\n") # 通过 keys 获取列名 print(first_data.keys()) print(first_data.keys()[0]) print("----------------end----------------\n") # 获取行的所有值 rows_data = first_data.values print(rows_data) print(rows_data[0]) print("----------------end----------------\n")
id class name age joywon 2001 1 joy won 10 joy 2001 2 joy 20 won 2003 3 won 30 ----------------end---------------- id 2001 class 1 name joy won age 10 Name: joywon, dtype: object ----------------end---------------- Index(['id', 'class', 'name', 'age'], dtype='object') id ----------------end---------------- Index(['id', 'class', 'name', 'age'], dtype='object') id ----------------end---------------- ['2001' 1 'joy won' 10] 2001 ----------------end----------------
4、Series的方法
-
Series
对象中有很多常用的方法可以对数据进行各种处理。例如,mean
方法可以对某一列的数据取平均数,min
方法可以取最小值,max
方法可以取最大值,std
方法可以取标准差。 -
例子:通过 mean、min、max、std 方法对数据进行处理
import pandas as pd df = pd.DataFrame( { 'name': ['joy won', 'joy', 'won'], 'age': [10, 20, 30], 'class': [1, 2, 3], 'id': ["2001", "2001", "2003"] }, # 更换列的数据输出顺序 columns = ['id', 'class', 'name', 'age'], index = ['joywon', 'joy', 'won'] ) print(df) print("----------------end----------------\n") # 获取数据集中 age 列的所有数据,返回一个 Series 对象 se_age = df['age'] print(se_age) print("----------------end----------------\n") # 平均数 print("mean=", se_age.mean()) # 最小值 print("min=", se_age.min()) # 最大值 print("max=", se_age.max()) # 标准差se print("std=", se_age.std()) print("----------------end----------------\n") # 对 se_age 降序排列 print(se_age.sort_values(ascending = False)) print("----------------end----------------\n") # 对 se_age 顺序排列 print(se_age.sort_values()) print("----------------end----------------\n") # 将 se_age 追加到自身上(这个方法在新版的pandas中会被删除,谨慎使用) print(se_age.append(se_age))
id class name age joywon 2001 1 joy won 10 joy 2001 2 joy 20 won 2003 3 won 30 ----------------end---------------- joywon 10 joy 20 won 30 Name: age, dtype: int64 ----------------end---------------- mean= 20.0 min= 10 max= 30 std= 10.0 ----------------end---------------- won 30 joy 20 joywon 10 Name: age, dtype: int64 ----------------end---------------- joywon 10 joy 20 won 30 Name: age, dtype: int64 ----------------end---------------- joywon 10 joy 20 won 30 joywon 10 joy 20 won 30 Name: age, dtype: int64
5、Series的条件过滤
-
Series
对象也可以像sql语句一样,通过指定条件来过滤数据。例如,列出年龄大于平均值的数据 -
例子:通过条件过滤对 Series 中的数据进行筛选
import pandas as pd df = pd.read_csv('./data/demo6.csv') se_age = df['age'] # 筛选出 age 大于平均值的数据,倒序取前3位 print(se_age[se_age > se_age.mean()].sort_values().head(3)) print("----------------end----------------\n") # 筛选出 age 大于平均值的数据,取前3位(输出形式不同) print((se_age > se_age.mean()).head(3)) print("----------------end----------------\n") # 指定哪行不显示,哪行显示,True表示显示,False表示不显示 print(se_age[ [True, False, True, True, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]])
4 32 8 32 22 32 Name: age, dtype: int64 ----------------end---------------- 0 False 1 False 2 True Name: age, dtype: bool ----------------end---------------- 0 10 2 33 3 12 5 21 Name: age, dtype: int64
6、DataFrame的条件过滤
-
DataFrame
和Series
类似,也可以使用条件进行过滤。# 获取age大于平均值的所有记录 df[df['age'] > df['age'].mean()]
-
例子:
import pandas as pd df = pd.read_csv("./data/demo6.csv") # 输出age大于平均值的2倍的记录 print(df[df['age'] > df['age'].mean() * 2]) print("----------------end----------------\n") # 如果不想繁琐,可以用这个方法实现输出第一行和第三行数据 print(df.loc[[True] + [False] + [True] + [False]*28]) print("----------------end----------------\n") # 通过索引输出指定行的数据 print(df.iloc[[1, 3, 4]]) print("----------------end----------------\n") # 输出age大于平均值的2倍的记录,只显示name,age,sex # 先指定列,再指定条件,或者先指定条件,再指定列也可以 print(df[['name', 'age', 'sex']][df['age'] > df['age'].mean() * 2]) print(df[df['age'] > df['age'].mean() * 2][['name', 'age', 'sex']]) print("----------------end----------------\n")
id name age sex city 13 14 afvaf 65 男 2 ----------------end---------------- id name age sex city 0 1 asd 10 男 1 2 3 ffgsg 33 男 3 ----------------end---------------- id name age sex city 1 2 asdfa 20 女 2 3 4 dfg 12 女 2 4 5 dfas 32 女 2 ----------------end---------------- name age sex 13 afvaf 65 男 name age sex 13 afvaf 65 男 ----------------end----------------