1.pandas数据结构
1.1 Series
Series是一种一维数组对象,包含一个值序列,通过索引(index)来访问数组中的数据。
·通过列表创建索引,并指定索引:
import pandas as pd
pd.Series(['a','b','c','d'],index=list('1234'))
输出结果:
1 a
2 b
3 c
4 d
dtype: object
·通过字典创建索引:
pd.Series({'a':100,'b':200,'c':300})
输出结果:
a 100
b 200
c 300
dtype: int64
传入一个字典则Series中的索引就是原字典中的键。
·通过字典创建Series并指定索引:
pd.Series({'a':1,'b':2,'d':300},index=list('abcd'))
输出结果:
a 1.0
b 2.0
c NaN
d 300.0
dtype: float64
如果字典中的键和指定的索引不匹配时,对应的值是NaN。
1.2 DataFrame
DataFrame是一种二维表格型的结构,既有行索引(index),也有列索引(columns)。在创建该结构时,可以指定相应的索引值。
·通过字典创建DataFrame:
data={
'name':['张三','李四','王五'],
'sex':['男','男','女'],
'year':[2002,2003,2004],
'city':['北京','上海','广州']
}
pd.DataFrame(data)
输出结果:
name sex year city
0 张三 男 2002 北京
1 李四 男 2003 上海
2 王五 女 2004 广州
DataFrame会自动加上索引跟Series一样。
·创建DataFrame并指定索引:
data={
'name':['张三','李四','王五'],
'sex':['男','男','女'],
'year':[2002,2003,2004],
'city':['北京','上海','广州']
}
pd.DataFrame(data,columns=['name','year','city','sex'])
输出结果:
name year city sex
0 张三 2002 北京 男
1 李四 2003 上海 男
2 王五 2004 广州 女
DataFrame的列会按索引顺序输出。
·DataFrame创建时的空缺值:
data={
'name':['张三','李四','王五'],
'sex':['男','男','女'],
'year':[2002,2003,2004],
'city':['北京','上海','广州']
}
pd.DataFrame(data,index=list('abc'),columns=['name','year','city','sex','address'])
输出结果:
name year city sex address
a 张三 2002 北京 男 NaN
b 李四 2003 上海 男 NaN
c 王五 2004 广州 女 NaN
DataFrame构造函数的columns给出列的名字,index给出label标签。
1.3 Index的常用方法和属性
方法 | 属性 |
---|---|
append | 连接另一个Index对象,产生一个新的Index |
delete | 删除索引i处的元素,并得到新的Index |
insert | 将元素插入索引i处,并得到新的Index |
is.monotonic | 当各元素均大于或等于前一个元素时,返回True |
is.unique | 当Index没有重复值时,返回True |
unique | 计算Index中唯一值的数组 |
2.DataFrame数据查询与编辑
2.1 数据查询
·通过列索引标签或属性方式单独选取列:
data={
'name':['张三','李四','王五'],
'sex':['男','男','女'],
'year':[2002,2003,2004],
'city':['北京','上海','广州']
}
df1=pd.DataFrame(data,index=list('abc'),columns=['name','year','city','sex','address'])
df1['name']
输出结果:
a 张三
b 李四
c 王五
Name: name, dtype: object
在选取列时不能使用切片方式。
·通过行索引或行索引位置的切片形式选取行数据:
data={
'name':['张三','李四','王五'],
'sex':['男','男','女'],
'year':[2002,2003,2004],
'city':['北京','上海','广州']
}
df1=pd.DataFrame(data,columns=['name','year','city','sex','address'])
print('显示前两行:\n',df1[:2])
输出结果:
显示前两行:
name year city sex address
0 张三 2002 北京 男 NaN
1 李四 2003 上海 男 NaN
·通过loc选取行和列
用法:DataFrame(行索引名称,列索引名称)
print('选取name和year列:\n',df1.loc[:,['name','year']])
输出结果:
选取name和year列:
name year
0 张三 2002
1 李四 2003
2 王五 2004
·通过iloc选取行和列
用法:DataFrame(行索引位置,列索引位置)
print('选取前两行前两列:\n',df1.iloc[:2,:2])
输出结果:
选取前两行前两列:
name year
0 张三 2002
1 李四 2003
·DataFrame常用属性和方法
方法 | 说明 |
---|---|
head() | 默认获取前5行 |
head(n) | 获取前n行 |
tail() | 默认获取后5行 |
tail(n) | 获取后n行 |
sample(n) | 随机抽取n行显示 |
sample(frac=0.6) | 随机抽取60%的行 |
T | 行和列转置 |
dtypes | 返回每列数据的数据类型 |
shape | 返回一个元组,表示DataFrame维度 |
size | DataFrame中的元素数量 |
2.2 数据编辑
·增加一行数据:通过append方法传入字典结构数据,参数ignore_index用以设置是否忽略原index。
d={'name':'赵六','year':2001,'city':'深圳','sex':'女'}
df1.append(d,ignore_index=True)
输出结果:
name year city sex address
0 张三 2002 北京 男 NaN
1 李四 2003 上海 男 NaN
2 王五 2004 广州 女 NaN
3 赵六 2001 深圳 女 NaN
·增加一列数据:只需要为新增的列赋值就行,若要指定位置可以用insert函数实现。
data={
'name':['张三','李四','王五'],
'sex':['男','男','女'],
'year':[2002,2003,2004],
'city':['北京','上海','广州']
}
df1=pd.DataFrame(data,columns=['name','year','city','sex','address'])
# 在索引位置为0的地方插入列
df1.insert(0,'num',['一','二','三'])
输出结果:
num name year city sex address
0 一 张三 2002 北京 男 NaN
1 二 李四 2003 上海 男 NaN
2 三 王五 2004 广州 女 NaN
删除数据直接用drop方法,通过aixs参数确定删除的是行还是列,默认数据删除不修改原数据,如果要修改原数据需要设置参数inplace=True。
·删除数据的列:
df2.drop('num',axis=1,inplace=True)
·删除数据的行:
df2.drop(3,axis=0,inplace=True)
2.3 修改数据
修改数据直接对选择的数据进行赋值即可。此外还有replace方法可以进行数据的替换。
使用loc:
df2.iloc[0,0]='张大'
输出结果:
name year city sex address
0 张大 2002 北京 男 NaN
1 李四 2003 上海 男 NaN
2 王五 2004 广州 女 NaN
·使用replace:
df2.replace(to_replace=df2.iloc[0,0],value='张总',inplace=True)
输出结果:
name year city sex address
0 张总 2002 北京 男 NaN
1 李四 2003 上海 男 NaN
2 王五 2004 广州 女 NaN
参数to_replace表示被替换的值;value表示替换后的值。同时替换多个值使用字典数据,例如d.replace({‘A’:‘B’,‘C’:‘D’})表示A替换成B,C替换成D。
·同时修改多个值:
df2.replace({'李四':'李总','王五':'王总'},inplace=True)
输出结果:
name year city sex address
0 张总 2002 北京 男 NaN
1 李总 2003 上海 男 NaN
2 王总 2004 广州 女 NaN
2.4 修改行列名
·修改行名:
df1.rename(index={0:'zero',1:'one'},inplace=True)
输出结果:
name year city sex address
zero 张三 2002 北京 男 NaN
one 李四 2003 上海 男 NaN
2 王五 2004 广州 女 NaN
·修改列名:
df1.rename(columns={'name':'姓名','year':'birth'},inplace=True)
输出结果:
姓名 birth city sex address
zero 张三 2002 北京 男 NaN
one 李四 2003 上海 男 NaN
2 王五 2004 广州 女 NaN
3.pandas数据运算
3.1 算术运算
·Series相加:
pd1=pd.Series([1,2,3],index=['a','b','c'])
pd2=pd.Series([4,5,6],index=['a','b','d'])
pd1+pd2
输出结果:
a 5.0
b 7.0
c NaN
d NaN
dtype: float64
如果有相同的索引则进行算术运算,如果没有则会进行数据对齐,但会引入缺失值。
·DataFrame类型的数据相加:
a=np.arange(1,10).reshape(3,3)
b=np.arange(1,7).reshape(2,3)
df3=pd.DataFrame(a,index=list('abc'),columns=list('ABC'))
df4=pd.DataFrame(b,index=list('ab'),columns=list('ABD'))
df3+df4
输出结果:
A B C D
a 2.0 4.0 NaN NaN
b 8.0 10.0 NaN NaN
c NaN NaN NaN NaN
对于DataFrame,数据对齐操作会同时发生在行和列上。
3.2 函数应用
·map函数:将函数套用到Series的每个元素中
例:在year列后面加个”年“字:
data={
'name':['张三','李四','王五'],
'sex':['男','男','女'],
'year':[2002,2003,2004],
'city':['北京','上海','广州']
}
df2=pd.DataFrame(data,columns=['name','year','city','sex'])
def f(x):
return str(x)+'年'
df2['year']=df2['year'].map(f)
输出结果:
name year city sex
0 张三 2002年 北京 男
1 李四 2003年 上海 男
2 王五 2004年 广州 女
这里DataFrame的一列是Series类型
·apply函数:将函数套用到DataFrame的行与列上,行与列通过参数axis设置
例:将每一行的数据都乘10:
df1=pd.DataFrame({'a':[10,40,50],'b':[20,30,60]})
df1.apply(lambda x:x*10,axis=0)
输出结果:
a b
0 100 200
1 400 300
2 500 600
3.3 常用描述性统计方法
方法 | 说明 |
---|---|
min | 最小值 |
max | 最大值 |
mean | 均值 |
median | 中位数 |
var | 方差 |
quantile | 四分位数 |
describe | 描述统计 |
ptp | 极差 |
std | 标准差 |
mode | 众数 |
count | 非空值数目 |
sum | 求和 |
pandas中通过unique方法获取不重复的数组;nunique方法计算行或列上唯一值的数量,即去重的数量;value_counts方法实现频数统计。
4.pandas数据排序并去除重复项
4.1 Series的排序
· sort_index()对索引进行排序:
df3=pd.Series([1,2,3,4],index=list('bcda'))
df3.sort_index()
输出结果:
a 4
b 1
c 2
d 3
dtype: int64
sort_values(ascending=True,inplace=False)对数值排序:
df3=pd.Series([3,5,1,2],index=list('abcd'))
df3.sort_values()
输出结果:
c 1
d 2
a 3
b 5
dtype: int64
4.2 DataFrame的排序
·sort_values(by,ascending=True,inplace=False)对数值排序:
df3.sort_values(by='year',ascending=False)
输出结果:
name year city sex
2 王五 2004年 广州 女
1 李四 2003年 上海 男
0 张三 2002年 北京 男
3 小明 2002年 深圳 男
4.3 去除重复项
drop_duplicates(subset,keep,inplace)方法:去除重复项,针对DataFrame类型数据,返回的是删除重复行的DataFrame数据。其中参数subset是用来指定特定的列;参数keep取值为first或last表示删除重复项并保留第一次或最后一次出现的项。
例:找到每年评分最高的电影。首先对每年上映的电影按评分降序排列如下
movie1[['电影名','评分','上映年份']].sort_values(['上映年份','评分'],ascending=[False,False])
输出结果:
但我们只要每一年评分最高的电影,所以同一年评分更低的电影就要删除
movie1[['电影名','评分','上映年份']].sort_values(['上映年份','评分'],ascending=[False,False]).drop_duplicates(subset='上映年份',keep='first')
输出结果:
5.数据分组与聚合
5.1 groupby方法基本用法
groupby的常用格式:DataFrame.groupby(by,axis,as_index,sort):
·by,分组字段,可以是列名,series,字典,函数等
·axis,操作的轴的方向,默认为0
·as_index,是否将分组列名作为输出的索引,默认为True
·sort,指定是否对输出结果按索引排序
案例:
·按列名分组,求平均值
· 按字典分组
· 按函数分组
5.2 数据聚合
数据聚合就是对分组后的数据进行计算,产生标量值的数据转换过程。
常用的聚合函数
函数 | 说明 |
---|---|
count | 计数 |
sum | 求和 |
mean | 求平均值 |
median | 求中位数 |
min,max | 最小值,最大值 |
prod | 求积 |
first,last | 第一个和最后一个值 |
std,var | 标准差和方差 |
注意:聚合运算中空值不参与计算。除了相关的函数实现聚合运算,还有自定义聚合运算。要使用自定义的聚合函数,需要将其传入agg方法或aggregate方法。
· 使用agg方法聚合数据
求工资奖金的平均值,最大值和最小值
agg能够实现对不同的字段应用不同的函数。
· transform方法
通过transform方法可以将运算分布到每一行,返回的是每一行相应的聚合结果。
例:按部门分组返回平均工资,平均奖金
·使用apply方法聚合数据
例:按部门分组计算平均工资与平均奖金的差
apply方法对groupby对象进行聚合操作的方法和agg方法相同,只是agg方法能实现对不同字段应用不同的函数,而apply不行。
6.数据合并
6.1 merge数据合并
格式:merge(left,right,how=‘inner’,on=None,left_on=None,right_on=None,left_index=False,right_index=False,sort=False)
·left:参与合并的左侧DataFrame
·right:参与合并的右侧DataFrame
·on:指的是用于连接的列索引名称
·how:表示连接方式,默认为inner(how取值有left:使用左侧DataFrame的键,类似于sql的左外连接;right:使用右侧的DataFrame的键;outer:使用两个DataFrame所有的键;inner:使用两个DataFrame的交集)
案列:
·左连接
·右连接
·外连接
6.2 concat数据连接
concat()函数可以沿着一条轴将多个对象进行堆叠。
格式:pd.concat(objs,axis=0,join=‘outer’,ignore_index=False…)
·axis:表示连接的轴向,默认为0
·join:连接的方式,默认为outer
·ignore_index:如果设置为True,清除现有索引并重新设置索引
案例:
· 以列方式连接
· 以行方式连接
pd.concat([df1,df2],axis=0)
输出结果:
6.3根据行索引合并数据(join)
格式:df1.join(df2,on=None,how,sort)
df1=pd.DataFrame(np.arange(12).reshape(3,4),index=list('ABC'),columns=list('abcd'))
df2=pd.DataFrame(np.arange(8).reshape(2,4),index=list('AB'),columns=list('1234'))
df1.join(df2)
输出结果:
6.4append纵向追加
· append追加Series
· append追加DataFrame
当列索引不一样时会自动补全
总结
1.merge主要用于指定列的横向拼接
2.concat可用于横向和纵向合并拼接
3.join最简单,主要用于索引的横向合并
4.append主要用于纵向追加
7.读取文件与文件存储
7.1 读取txt文件
格式:pandas.read_table(filepath,sep=’\t’,header=‘infer’,names=None,encoding…)
·filepath:文件路径
·sep:代表分隔符
·header:表示将某行数据作为列名,默认为infer表示自动识别
·names:接收array,表示列名,默认为None
·encoding:编码格式
7.2 读取csv文件
格式:pandas.read_csv(filepath,sep=’\t’,header=‘infer’,names=None…)
7.3 读取xls和xlsx文件
格式:pandas.read_excel(io,sheetname,header=’infer‘,dtype…)
·io:文件路径
·sheetname:代表excel表内数据的分表位置,默认为0
·header:表示将某行数据作为列名,默认为infer表示自动识别
·dype:接收dict,代表写入的数据类型 ,默认为None
7.4 文件的存储
· 文本文件的存储
格式:DataFrame.to_csv(path,sep=’,’,header=True,index=True…)
· excel文件的存储
格式:DataFrame.to_excel(excel_write,sheetname=None,header=True,index=True…)