pandas进阶教程


进阶操作

复杂查询

逻辑运算

df.Q1 > 36
df.index == 1
df.loc[:,'Q1':'Q4'] > 60
#Pandas支持很多逻辑运算,这里不再介绍

函数筛选

# 可以在表达式处使用lambda函数
df.Q1[lambda s: max(s.index)] #查询最大的索引值

lambda 形式参数:函数表达式

比较函数

pandas提供了一些比较函数,使我们可以将逻辑表达式替换为函数形式

df.eq()		#等于
df.ne()		#不等于
df.le()		#小于等于
df.lt()		#小于
df.ge()		#大于等于
df.gt()		#大于

df.query()查询

df.query(expr)		#使用布尔表达式查询df的列
#举例
df.query('Q1>Q2>90')
df.query('Q1+Q2>180')
df.query('Q1==Q2')
df.query('(Q1<50) & (Q2>40) and (Q3>90)')
#支持使用@符号引入变量
a = df.Q1.mean()
df.query('Q1 > @a+40')
df.eval()			#与.query()类似

df.filter()筛选

df.filter()		#行名和列名进行筛选,支持模糊匹配、正则表达式。
例:
df.filter(items=['Q1','Q2'])	#选择两列
df.filter(regex='Q',axis=1)		#列名包含Q的列
df.filter(regex='e$',axis=1)	#以e结尾的列
df.filter(regex='1$',axis=0)	#正则,索引名以1结尾的行
df.filter(like='2',axis=0)		#索引中有2的行
df.filter(regex='^2',axis=0).filter(like='Q',axis=1)

按数据类型查询

df.select_dtypes(include=None, exclude=None)
include: 'float64' \ 'bool' \ 'number'
exclude: 同上

数据类型转换

#推断类型
df.infer_objects()	#自动转换合适的数据类型
df.convert_dtypes()	#自动转换,支持str类型
#指定类型
pd.to_XXX()
pd.to_numeric(,downcast='integer')#转为数字,且是int,而非float
	#downcast:integer\signed\unsigned\float
pd.to_datetime(,errors='ignore')#转为时间
pf.to_datetime(,format='%Y-%m-%d')
pd.to_timedelta(,errors='coerce')#转为时间差
pd.to_datatime(df[['year','month','day']])#组合成日期
#类型转换astype()
df.column.astype('int32')
df.astype({'Q1':'int32','Q2':'int32'})
	#当数据的格式不具备转换为目标类型的条件时,需要先对数据进行处理。
	#例如:80%
data.rate.apply(lambda x: x.replace('%','')).astype('float')/100

转换为时间类型

这里我想拿出来单独做笔记,因为我经常被时间类型是比较弄的焦头烂额。

pd.to_datatime()
s.astype('datatime64[ns]')
例:
t = pd.Series(['202000101','20001103'])

以上这些当转换格式挺好用,但如果筛选时间段,我建议还是用str类型,正则表达式比较好用,例如:

#筛选2000年以后的数据
data_20 = data[data.filter(regex='^20',ax=0)]
#正则表达式什么时候用查百度就行

数据排序

#索引排序
df.sort_index()
df.sort_index(ascending=False)		#倒序
df.sort_index(axis=1)				#列索引
df.sort_index(inplace=True)			#改变原数据
df.sort_index(ignore_index=True)	#重新建立索引
df.sort_index(na_position='first')	#空值在前'last'
df.reindex()						#指定自己定义顺序的索引
#数值排序
df.sort_values()
df.sort_values(by= ,ascending= )	#上面的参数也都有效
#按大小值排序
df.nsmallest(5, [])					#按[]中列名排序,显示最小的5行数据
df.nlargest()

添加修改

.replace.fillna.rename.set_axis.insert.assign.eval.append.concat.dropna
#替换数据
df.replace(0,5)				#0换5
df.replace([0,1,2],3)		#012换3
df.replace([0,1,2],[3,4,5])	#对应替换
s.replace([1,2],method='bfill')#下一位作为填充
	#method:pad(上下均值)\ffill\bfill
df.replace({})				#字典对应替换
df.replace({'Q1':1},100)	#将Q1中的值1换为100
df.repalce({'Q1':{1:10,2:20}})#指定Q1列中的值1、2换为10、20
#正则表达式
df.replace(to_replace=r'',value='new',regex=True)
df.replace({'Q1':r''},{'Q1':'new'},regex=True)
df.replace(regex={r'':'new' 'foo':'xyz'})
df.replace(regex=[r'', 'foo'],value='new')
#填充空值
df.fillna(0)				#全部填充为0
	#method: backfill\bfill\pad\ffill\None
values = {'A':0,'B':1}
df.fillna(value=values)		#为各列按字典填充不同的值
df.fillna(value=values,limit=1)#只替换第一个
#修改索引名
df.rename(columns={'team':'class'})
df.rename(index=str)		#d对类型进行修改
df.rename(str.lower,axis='columns')#传索引类型
df.rename_axis('animal')
	#可以用set_axis进行修改设置
df.set_axis(['a', 'b', 'c'], axis=0)
#增加列
	#把所有为数字的值相加
df['total']=df.select_dtypes(include=['int'].sum(1))
df['total']=df.loc[:,'Q1':'Q4'].apply(lambda x:sum(x),axis='columns')
#插入列
df.insert(loc,column,value)
	#loc:插入位置,+1就是第几列
	#column:列名,value:列值
	#已存在相同列会报错,allow_duplicates=True插入一个同名的列
#指定列
df.assign(k=v)	#指定一个新列,k为列名,v为值,v必须是一个与原数据同索引的series
df.assign(total=df.sum(1))
#增加两列
df.assign(total=df.sum(1).assign(Q=100))#增加了total和Q列而已
#链式方法
{
	df.assign(total=df.sum(1))
	.assign(Q=100)
	.assign(name_len=df.name.str.len())
}
#执行表达式
df.eval('k=v')			#可以以字符形式传入表达式,增加列数据
#增加行
df.loc[100]=['','', , ]	#给新增第一百行加数据
df.loc[101]={'Q1':88,'Q2':99}#指定列加数据,无为NA
#追加合并
df1.append(df2)
pd.concat(				#增加一个一层索引key取名Series name,变多层索引
		[s1,s2],
		keys=['s1','s2'],
		names=['Series name','Row ID'])
'''
Series name  Row ID
s1           0         1
             1         2
s2           0         a
             1         b
'''
pd.concat(
		[df1,df2],
		sort=False,
		join="inner",	#只连相同列
		axis=1)			#连接列
#删除
df.pop()
#删除空值
df.dropna()		#一行中有一个缺失值就删除
df.dropna(
		axis='columns',		
		how='all',			#全部值为NA才删除
		thresh=2,			#至少有两个空值时才删除
		inplace=True)

高级过滤

.select_dtypes.where\np.where.mask.lookup
df.select_dtypes(includ='number')
df.where(df>70)		#符合条件的保留,其他填充为NA
df.Q1.where(pd.Series([True]*3))#前三个原值,其他为NA
df.where(df>=60,'不及格')	#可以指定一个值替换NAN
c = df%2==0
df.where(~c,-(df-20))
#np.where()对满足条件的值进行修改
np.where(df>=60,'合格','不合格')#返回的是一个二维array
	#让条件为假,从而应用np.where的计算结果
df.where(df==999999,np.where(df>60,'合格','不合格'))
{
	df.assign(avg=mean(1))
	.assign(及格=lambda d:np.where(d.avg>=60,'是','否'))
}
#df.mask()用法与df.where()基本相同
df.mask(s>80)		#将满足位置填充为NA
#df.lookup(行标签,列标签)		#返回一个array,查看
df.lookup([1,3,4],['Q1','Q2'])

数据迭代

.zip.interrows.itertuples.item

df.name.values返回array结构可用于迭代

#迭代指定的列
for i in df.name:
	print(i)
#迭代索引和指定的两列,zip用于打包
for i,n,q in zip(df.index, df.name, df.Q1)
	print(i,n,q)
#df.iterrows(),将df由(索引,行数据)组成Series对象进行迭代
for index, row in df.interrows():
	print(index,row['name'],row.Q1)
#df.itertuples(),生成一个namedtuples类型数据,更快
for row in df.itertuples():
	print(row)
'''
Pandas(Index=0,Q1=89,Q2=21)
Pandas(Index=1,Q1=57,Q2=60)
'''
df.itertuples(
			index=False,	#不包含索引数据
			name='')		#自定义name,就是把Pandas替换
#df.items(),返回一个(列名,本列的Series结构数据)
'''输出所有列
Q1
0	12
1	15
Name:Q1,dtype:int64
Q2
0	48
1	66
Name:Q2,dtype:int64
'''
#按列迭代
for column in df:	
	print(column)

函数应用

pip()/apply()/applymap()/map()
#pipe()管道方法
#它可以让我们写的分析过程标准化、流水线化,
#达到复用目标,它也是最近非常流行的链式方法的重要代表。
df.pipe(<函数名>,<传给函数的参数列表或字典>)
#对df多重应用多个函数
f(g(h(df), arg1=a), arg2=b, arg3=c)
#用pipe可以把它们连接起来
(
	df.pipe(h)
	.pipe(g, arg1=a)
	.pipe(f, arg2=b, arg3=c)
)
#将'arg2'参数传给函数f,然后作为函数整体接受后面的参数
(
	df.pipe(h)
	.pipe(g,arg1=a)
	.pipe((f,'arg2'),arg1=a,arg3=c)
)
#df_,使用前数据本身
df.pipe(lambda df_,x,y: df_[(df_.Q1>=x)&(df_.Q2>=y)],80,90)
	#筛选处Q1大于等于80且Q2大于等于90的数据
#apply()
#apply()可以对df按行和列进行函数处理,series传入具体值
#判断一个值是否在另一个类似列表的列中
df.apply(lambda d: d.s in d.s_list,axis=1)#布尔序列
df.apply(lambda d: d.s in d.s_list,axis=1).astype(int)#0\1序列
#经常配合np.where()使用
fun = lambda x:np.where(x.team=='A' and x.Q1>90, 'good','other')
df.apply(fun,axis=1)
#其他写法
(
	df.apply(lambda x:x.team=='A' and x.Q1>90, axis=1)
	.map({True:'good', False:'other'})
)
df.apply(lambda x:'good' if x.team=='A' and x.Q1>90 else '',axis=1)
df.apply(fun)		#自定义
df.apply(max)		#内置函数,pandas自己的函数
df.apply(lambda)	#匿名函数
df.apply(np.mean)	#其他库的函数
#applymap()元素级函数应用
df.applymap(参数为单个数据的函数)
#map(),输入对应关系映射值返回最终数据
df.team.map('I am {}'.format, na_action='ignore')
#agg()使用指定轴上的一项或多项操作进行汇总
df.agg('max')			#每列的最大值
df.agg(['sum','min'])	#将所有列聚合产生sum和min两行
df.agg({'Q1':['sum','min'],'Q2':['min','max']})#序列多个聚合
#分组后聚合
df.groupby('team').agg('max')
df.Q1.agg(['sum','mean'])
#每列使用不同方法进行聚合
df.agg(
		a=('Q1',max),
		b=('Q2',min))
df.loc[:,'Q1':].agg(pd.Series.add, other=10)
#transform()返回的是原数据的结构
df.transform(lambda x: x*2)		#应用匿名函数
df.transform([np.sqrt, np.exp])	#调用多个函数
df.transform({'A': np.abs, 'B': lambda x: x+1})
#copy()返回一个新对象,且与原对象没有关系deep=T是默认
df_copy = df.copy()

参考内容:《深入浅出Pandas》


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值