Python pandas轴旋转stack和unstack的使用说明!
摘要
前面给大家分享了pandas做数据合并的两篇[pandas.merge]和[pandas.cancat]的用法。今天这篇主要讲的是pandas的DataFrame的轴旋转操作,stack和unstack的用法。
首先,要知道以下五点:
1.stack:将数据的列“旋转”为行
2.unstack:将数据的行“旋转”为列
3.stack和unstack默认操作为最内层
4.stack和unstack默认旋转轴的级别将会成果结果中的最低级别(最内层)
5.stack和unstack为一组逆运算操作
第一点和第二点以及第五点比较好懂,可能乍看第三点和第四点会不太理解,没关系,看看具体下面的例子,你就懂了。
1、创建DataFrame,行索引名为state,列索引名为number
importpandasaspd importnumpyasnp data=pd.DataFrame(np.arange(6).reshape((2,3)),index=pd.Index(['Ohio','Colorado'],name='state') ,columns=pd.Index(['one','two','three'],name='number')) data
2、将DataFrame的列旋转为行,即stack操作
result=data.stack() result
从下图中结果来理解上述点4,stack操作后将列索引number旋转为行索引,并且置于行索引的最内层(外层为索引state),也就是将旋转轴(number)的结果置于最低级别。
3、将DataFrame的行旋转为列,即unstack操作
result.unstack()
从下面结果理解上述点3,unstack操作默认将内层索引number旋转为列索引。
同时,也可以指定分层级别或者索引名称来指定操作级别,下面做错同样会得到上面的结果。
4、stack和unstack逆运算
s1=pd.Series([0,1,2,3],index=list('abcd')) s2=pd.Series([4,5,6],index=list('cde')) data2=pd.concat([s1,s2],keys=['one','two']) data2
data2.unstack().stack()
补充:使用Pivot、Pivot_Table、Stack和Unstack等方法在Pandas中对数据变形(重塑)
Pandas是著名的Python数据分析包,这使它更容易读取和转换数据。在Pandas中数据变形意味着转换表或向量(即DataFrame或Series)的结构,使其进一步适合做其他分析。在本文中,小编将举例说明最常见的一些Pandas重塑功能。
一、Pivot
pivot函数用于从给定的表中创建出新的派生表,pivot有三个参数:索引、列和值。具体如下:
defpivot_simple(index,columns,values): """ Produce'pivot'tablebasedon3columnsofthisDataFrame. Usesuniquevaluesfromindex/columnsandfillswithvalues. Parameters ---------- index:ndarray Labelstousetomakenewframe'sindex columns:ndarray Labelstousetomakenewframe'scolumns values:ndarray Valuestouseforpopulatingnewframe'svalues
作为这些参数的值需要事先在原始的表中指定好对应的列名。然后,pivot函数将创建一个新表,其行和列索引是相应参数的唯一值。我们一起来看一下下面这个例子:
假设我们有以下数据:
我们将数据读取进来:
fromcollectionsimportOrderedDict frompandasimportDataFrame importpandasaspd importnumpyasnp data=OrderedDict(( ("item",['Item1','Item1','Item2','Item2']), ('color',['red','blue','red','black']), ('user',['1','2','3','4']), ('bm',['1','2','3','4']) )) data=DataFrame(data) print(data)
得到结果为:
itemcoloruserbm 0Item1red11 1Item1blue22 2Item2red33 3Item2black44
接下来,我们对以上数据进行变形:
df=data.pivot(index='item',columns='color',values='user') print(df)
得到的结果为:
colorblackbluered item Item1None21 Item24None3
注意:可以使用以下方法对原始数据和转换后的数据进行等效查询:
#原始数据集 print(data[(data.item=='Item1')&(data.color=='red')].user.values) #变换后的数据集 print(df[df.index=='Item1'].red.values)
结果为:
['1'] ['1']
在以上的示例中,转化后的数据不包含bm的信息,它仅包含我们在pivot方法中指定列的信息。下面我们对上面的例子进行扩展,使其在包含user信息的同时也包含bm信息。
df2=data.pivot(index='item',columns='color') print(df2)
结果为:
userbm colorblackblueredblackbluered item Item1None21None21 Item24None34None3
从结果中我们可以看出:Pandas为新表创建了分层列索引。我们可以用这些分层列索引来过滤出单个列的值,例如:使用df2.user可以得到user列中的值。
二、PivotTable
有如下例子:
data=OrderedDict(( ("item",['Item1','Item1','Item1','Item2']), ('color',['red','blue','red','black']), ('user',['1','2','3','4']), ('bm',['1','2','3','4']) )) data=DataFrame(data) df=data.pivot(index='item',columns='color',values='user')
得到的结果为:
ValueError:Indexcontainsduplicateentries,cannotreshape
因此,在调用pivot函数之前,我们必须确保我们指定的列和行没有重复的数据。如果我们无法确保这一点,我们可以使用pivot_table这个方法。
pivot_table方法实现了类似pivot方法的功能,它可以在指定的列和行有重复的情况下使用,我们可以使用均值、中值或其他的聚合函数来计算重复条目中的单个值。
首先,我们先来看一下pivot_table()这个方法:
defpivot_table(data,values=None,index=None,columns=None,aggfunc='mean', fill_value=None,margins=False,dropna=True, margins_name='All'): """ Createaspreadsheet-stylepivottableasaDataFrame.Thelevelsinthe pivottablewillbestoredinMultiIndexobjects(hierarchicalindexes)on theindexandcolumnsoftheresultDataFrame Parameters ---------- data:DataFrame values:columntoaggregate,optional index:column,Grouper,array,orlistoftheprevious Ifanarrayispassed,itmustbethesamelengthasthedata.Thelist cancontainanyoftheothertypes(exceptlist). Keystogroupbyonthepivottableindex.Ifanarrayispassed,it isbeingusedasthesamemannerascolumnvalues. columns:column,Grouper,array,orlistoftheprevious Ifanarrayispassed,itmustbethesamelengthasthedata.Thelist cancontainanyoftheothertypes(exceptlist). Keystogroupbyonthepivottablecolumn.Ifanarrayispassed,it isbeingusedasthesamemannerascolumnvalues. aggfunc:functionorlistoffunctions,defaultnumpy.mean Iflistoffunctionspassed,theresultingpivottablewillhave hierarchicalcolumnswhosetoplevelarethefunctionnames(inferred fromthefunctionobjectsthemselves) fill_value:scalar,defaultNone Valuetoreplacemissingvalueswith margins:boolean,defaultFalse Addallrow/columns(e.g.forsubtotal/grandtotals) dropna:boolean,defaultTrue DonotincludecolumnswhoseentriesareallNaN margins_name:string,default'All' Nameoftherow/columnthatwillcontainthetotals whenmarginsisTrue. 接下来我们来看一个示例: data=OrderedDict(( ("item",['Item1','Item1','Item1','Item2']), ('color',['red','blue','red','black']), ('user',['1','2','3','4']), ('bm',['1','2','3','4']) )) data=DataFrame(data) df=data.pivot_table(index='item',columns='color',values='user',aggfunc=np.min) print(df)
结果为:
colorblackbluered item Item1None21 Item24NoneNone
实际上,pivot_table()是pivot()的泛化,它允许在数据集中聚合具有相同目标的多个值。
三、Stack/Unstack
事实上,变换一个表只是堆叠DataFrame的一种特殊情况,假设我们有一个在行列上有多个索引的DataFrame。堆叠DataFrame意味着移动最里面的列索引成为最里面的行索引,反向操作称之为取消堆叠,意味着将最里面的行索引移动为最里面的列索引。例如:
frompandasimportDataFrame importpandasaspd importnumpyasnp #建立多个行索引 row_idx_arr=list(zip(['r0','r0'],['r-00','r-01'])) row_idx=pd.MultiIndex.from_tuples(row_idx_arr) #建立多个列索引 col_idx_arr=list(zip(['c0','c0','c1'],['c-00','c-01','c-10'])) col_idx=pd.MultiIndex.from_tuples(col_idx_arr) #创建DataFrame d=DataFrame(np.arange(6).reshape(2,3),index=row_idx,columns=col_idx) d=d.applymap(lambdax:(x//3,x%3)) #Stack/Unstack s=d.stack() u=d.unstack() print(s) print(u)
得到的结果为:
c0c1 r0r-00c-00(0,0)NaN c-01(0,1)NaN c-10NaN(0,2) r-01c-00(1,0)NaN c-01(1,1)NaN c-10NaN(1,2) c0c1 c-00c-01c-10 r-00r-01r-00r-01r-00r-01 r0(0,0)(1,0)(0,1)(1,1)(0,2)(1,2)
实际上,Pandas允许我们在索引的任何级别上堆叠/取消堆叠。因此,在前面的示例中,我们也可以堆叠在最外层的索引级别上。但是,默认(最典型的情况)是在最里面的索引级别进行堆叠/取消堆叠。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。