Python数据分析pandas之dataframe初识
声明与简介
pandas是一个基于python的、快速的、高效、灵活、易用的开源的数据处理、分析包(工具)。。pandas构建在numpy之上,它通过DataFrame(数据框)来操作数据。数据框是一个高效的可以指定行和列标签的多维数组,通过这种数据类型可以更方便的操作、分析数据。本文主要介绍DataFrame的初始化和访问、缺失值处理的常见方法。
创建DataFrame
DataFrame可以看作是二维数组的模拟,可以通过行索引和列名对数组进行检索。数据框是二维的,由行和列组成,类似数据库里的二维表的概念(众多行和列组成)。
我们也可以把DataFrame看作是特殊的Numpy数组或者Python字典对象。
DataFrame(二维数组)是有一对排序有序的Series(一维数组)组成的,这里的有序指的是他们有相同的索引。
拼接字典方式的Series
#以学生学号、姓名、年龄的学生信息的DataFrame为例,演示DataFrame与Series的关系。
import pandas as pd
age={
"no_001":28,
"no_002": 32,
"no_003": 19
}
name={
"no_001":"张三",
"no_002": "李四",
"no_003":"王二"
}
df= pd.DataFrame({"name":name,"age":age})
print(df)
#结果
name age
no_001 张三 28
no_002 李四 32
no_003 王二 19
#这里不难发现,Series name和Series age有相同的序列,即索引系统。这里可以理解为记录序号或者学号。
二维Numpy数组
#通过Numpy数组的方式创建以学号为索引,含姓名和年龄的学生信息的数据框
import pandas as pd
df=pd.DataFrame([["张三",28],["李四",32],["王二",19]],columns=[ 'name','age',],index=['no_001','no_002','no_003'])
print(df)
#结果
name age
no_001 张三 28
no_002 李四 32
no_003 王二 19
由结构化(体)数组创建
#通过一个结构体将分开的数组串成一个整体。这里的结构体类似于C语言里的Struct,可以理解为一些有意义的个体内容的整合。
import pandas as pd
name=["张三","李四","王二"]
age=[28,32,19]
data = np.zeros(3, dtype={'names': ('name', 'age'),'formats': ('U10', 'i4')})
data['name']=name
data['age']=age
#打印结构体的数据内容
print(data)
df=pd.DataFrame(data,columns=['name','age'],index=['no_001','no_002','no_003'])
print(df)
#结果
[('张三', 28) ('李四', 32) ('王二', 19)]
name age
no_001 张三 28
no_002 李四 32
no_003 王二 19
访问DataFrame
字典方式
#该方式主要是指DataFrame是由字典形式的Series组成的,访问元素时可以采用字典方式。
#当前需求是仅访问name列,即显示所有人的姓名
import pandas as pd
age={
"no_001":28,
"no_002": 32,
"no_003": 19
}
name={
"no_001":"张三",
"no_002": "李四",
"no_003":"王二"
}
df= pd.DataFrame({"name":name,"age":age})
print(df['name'],df.name)
#结果
no_001 张三
no_002 李四
no_003 王二
Name: name, dtype: object no_001 张三
no_002 李四
no_003 王二
Name: name, dtype: object
二维Numpy数组
#通过Numpy数组的方式创建以学号为索引,含姓名和年龄的学生信息的数据框
import pandas as pd
df=pd.DataFrame([["张三",28],["李四",32],["王二",19]],columns=[ 'name','age',],index=['no_001','no_002','no_003'])
print(df.values)
#结果
[['张三' 28]
['李四' 32]
['王二' 19]]
通过loc或iloc访问
#针对字典方式或二维数组方式创建的DataFrame都可通过loc和iloc方法进行行和列的过滤来访问数据框里的元素。
#通过loc或者iloc访问数据框的内容
import pandas as pd
name=["张三","李四","王二"]
age=[28,32,19]
data = np.zeros(3, dtype={'names': ('name', 'age'),'formats': ('U10', 'i4')})
data['name']=name
data['age']=age
df1= pd.DataFrame(data,columns=['name','age'],index=['no_001','no_002','no_003'])
import pandas as pd
df2 = pd.DataFrame([["张三", 28], ["李四", 32], ["王二", 19]], columns=['name', 'age', ],
index=['no_001', 'no_002', 'no_003'])
print(df1.loc['no_001'])
print(df1.loc['no_001']['name'])
print(df2.loc['no_001']['name'])
print(df2.iloc[1])
#结果
name 张三
age 28
Name: no_001, dtype: object
张三
张三
name 李四
age 32
Name: no_002, dtype: object
通过loc或iloc过滤
#针对字典方式或二维数组方式创建的DataFrame都可通过loc和iloc方法进行行和列的过滤来访问数据框里的元素。
#通过loc或者iloc访问带过滤条件的数据框内容,这里仅显示年龄大于30的学生姓名。
import pandas as pd
name=["张三","李四","王二"]
age=[28,32,19]
data = np.zeros(3, dtype={'names': ('name', 'age'),'formats': ('U10', 'i4')})
data['name']=name
data['age']=age
df1= pd.DataFrame(data,columns=['name','age'],index=['no_001','no_002','no_003'])
import pandas as pd
df2 = pd.DataFrame([["张三", 28], ["李四", 32], ["王二", 19]], columns=['name', 'age', ],
index=['no_001', 'no_002', 'no_003'])
print(df1.loc[data['age']>30,['name']])
#如果第2行里age大于30那么就显示它的姓名
print(df1.name[df1.iloc[1]['age'] > 30])
#结果
name
no_002 李四
李四
通过loc或iloc切片
#可以通过loc或者iloc对数据框进行切片式访问。
#行切示例,分别以loc或iloc方式仅取出no_002、no_003对应的内容
import pandas as pd
name=["张三","李四","王二"]
age=[28,32,19]
data = np.zeros(3, dtype={'names': ('name', 'age'),'formats': ('U10', 'i4')})
data['name']=name
data['age']=age
df1= pd.DataFrame(data,columns=['name','age'],index=['no_001','no_002','no_003'])
import pandas as pd
df2 = pd.DataFrame([["张三", 28], ["李四", 32], ["王二", 19]], columns=['name', 'age', ],
index=['no_001', 'no_002', 'no_003'])
print(df1.loc['no_002':'no_003'])
print(df2.iloc[0:1])
#结果
name age
no_002 李四 32
no_003 王二 19
name age
no_001 张三 28
DataFrame处理缺失值
None填充缺失值
该方式用None来补充缺失值,因为None是空对象,而Numpy、Series、DataFrame都属于Padans且继承自Object对象,所以可以被赋值为None,即空对象。
#利用None作为空元素填充到数据框里。
import pandas as pd
df2 = pd.DataFrame([["张三", 28], ["李四", 32], [None, 19]], columns=['name', 'age',],index=['no_001', 'no_002', 'no_003'])
print(df2)
#结果
name age
no_001 张三 28
no_002 李四 32
no_003 None 19
#注:None不可以参与任何的元素运算,比如None+3是非法的。
NaN填充缺失的数值
#通过numpy的NAN方法对缺失、空的数值型进行填充。
import pandas as pd df2 = pd.DataFrame([["张三", 28], ["李四", 32], ["王二",np.nan]], columns=['name', 'age', ],index=['no_001', 'no_002', 'no_003']) print(df2)
print(df2['age'].sum()) #结果
name age no_001 张三 28.0 no_002 李四 32.0 no_003 王二 NaN
60.0
#1这里的np.nan是float类型。
#2由此可见DataFrame做列的sum时会将NaN值认为是0.0。
#这里的NAN可以做运算,比如NaN+3还是NaN。示例如下:
import numpy as np vals2 = np.array([1,3, 4,np.nan]) print(vals2.sum())
#结果
nan
Null notnull判断空值
#1 通过isnull来判断数据框里的列是否有None或者nan的情况
import pandas as pd
df2 = pd.DataFrame([["张三", None], ["李四",32 ], ["王二",np.nan]], columns=['name', 'age', ],index=['no_001', 'no_002', 'no_003'])
print(df2.isnull())
#结果
name age
no_001 False True
no_002 False False
no_003 False True
#2 同理利用notnull,提取age列不为空的数据。
import pandas as pd
df2 = pd.DataFrame([["张三", None], ["李四",32 ], ["王二",np.nan]], columns=['name', 'age', ],index=['no_001', 'no_002', 'no_003'])
print(df2[df2['age'].notnull()])
#结果
name age
no_002 李四 32.0
用所在列前值填充空数据
#此种方式是用ffill方法即当前列里为空元素的前一个元素来补充当前为空的元素。
import pandas as pd
df2 = pd.DataFrame([["张三", 28,80,1], [None,32,90,2 ], ["王二",np.nan,99,1]], columns=['name', 'age','score','level'],index=['no_001', 'no_002', 'no_003'])
print(df2.fillna(method='ffill'))
#结果,不难发现no_002的name被no_001的name填充,同理no_003的age被no_002的填充。
name age score level
no_001 张三 28.0 80 1
no_002 张三 32.0 90 2
no_003 王二 32.0 99 1
用所在列后值填充空数据
#此种方式是用bfill方法即当前列里为空元素的前一个元素来补充当前为空的元素。
import pandas as pd
df2 = pd.DataFrame([["张三", 28,80,1], [None,32,90,2 ], ["王二",np.nan,99,1]], columns=['name', 'age','score','level'],index=['no_001', 'no_002', 'no_003'])
print(df2.fillna(method='bfill'))
#结果,不难发现这里no_002的name被no_003的name填充,而因为no_003是最后的记录,所以无法再被填充,所以age只能还是NaN。
name age score level
no_001 张三 28.0 80 1
no_002 王二 32.0 90 2
no_003 王二 NaN 99 1
用固定值填充空数据
#此种方式即fillna时指定固定的值,比如0或者列的均值等。
import pandas as pd
df2 = pd.DataFrame([["张三", 28,80,1], [None,32,90,2 ], ["王二",np.nan,99,1]], columns=['name', 'age','score','level'],index=['no_001', 'no_002', 'no_003'])
print(df2.fillna(0))
#结果
name age score level
no_001 张三 28.0 80 1
no_002 0 32.0 90 2
no_003 王二 0.0 99 1
以列方向删除空值
#这种方式从列这个角度(axis='columns')去删除为None或者Nan的数据,但凡某一列含有空就删除该列,输出列数取决于不含空的列的个数。
import pandas as pd
df2 = pd.DataFrame([["张三", 28,80], [None,32,90 ], ["王二",np.nan,99]], columns=['name', 'age','score' ],index=['no_001', 'no_002', 'no_003'])
print(df2.dropna(axis='columns'))
#结果
score
no_001 80
no_002 90
no_003 99
#注:axis='columns'等价于axis=1
以行方向删除空值
#这种方式从行这个角度(axis='rows')去删除为None或者Nan的数据,但凡某一行含有空就删除该行,输出列数与原数据的列数一致或者为空。
import pandas as pd
df2 = pd.DataFrame([["张三", 28,80], [None,32,90 ], ["王二",np.nan,99]], columns=['name', 'age','score' ],index=['no_001', 'no_002', 'no_003'])
print(df2.dropna())
print(df2.dropna(axis='rows'))
#结果
name age score
no_001 张三 28.0 80
#注 1注:axis='rows'等价于axis=0
#2如果不指定axis那么就会从行、列方向做删除操作。
以最小非空阀值删除空值
#该方式是指定thresh参数以限定行或者列的最小非空的个数,即最小非空阈值。标签:name,no,Python,age,dataframe,003,002,001,pandas From: https://blog.51cto.com/u_15080860/6075986
#当前示例有姓名、年龄、分数、等级4列,3条数据,这里因为设置了最小非空阈值,所以输出结果里有的列是None或者Nan是正常的。
import pandas as pd
df2 = pd.DataFrame([["张三", 28,80,1], [None,32,90,2 ], ["王二",np.nan,99,1]], columns=['name', 'age','score','level'],index=['no_001', 'no_002', 'no_003'])
print(df2.dropna())
print(df2.dropna(axis='rows',thresh=3))
#结果
name age score level
no_001 张三 28.0 80 1
no_002 None 32.0 90 2
no_003 王二 NaN 99 1