Pandas 旋转数据,实际应用中,按行或列调整元素并不总能满足目标,有时,需要按照行重新调整列的元素或者按照列调整行的元素,本章介绍DataFrame转置,通过stack()
和unstack()
实现按索引旋转,pivot()
实现长格式向宽格式的旋转。
DataFrame 转置
pandas教程中的DataFrame 属性和方法有简单介绍DataFrame转置,转置实现行和列的交换,通过T
完成,如下所示:
import pandas as pd
d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Minsu','Jack']),
'Age':pd.Series([25,26,25,23,30,29,23]),
'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])}
df = pd.DataFrame(d)
print (df)
print('------------')
print (df.T)
输出结果如下:
按等级索引旋转
前面讲过,DataFrame对象支持等级索引,利用这一点,可以重新调整DataFrame对象中的数据,轴向旋转有两个基础操作。
- 入栈(Stacking):旋转数据结构,把列转换为行。
- 出栈(unStacking):把行转换为列。
如下所示,对DataFrame()对象应用stack()函数,会把列转换为行,从而得到一个Series
对象。
import pandas as pd
import numpy as np
dframe = pd.DataFrame(np.arange(9).reshape(3,3),
index=['white', 'black', 'red'],
columns=['ball', 'pen', 'pencil'])
print(dframe)
print('------------')
print(dframe.stack())
输出结果如下:
在这个具有等级索引结构的Series对象上执行unstack()
操作,可以重建之前的DataFrame对象,从而可以以数据透视表的形式来展示Series
对象中的等级索引结构。
import pandas as pd
import numpy as np
dframe = pd.DataFrame(np.arange(9).reshape(3,3),
index=['white', 'black', 'red'],
columns=['ball', 'pen', 'pencil'])
ser = dframe.stack()
print(ser.unstack())
输出结果如下:
出栈操作可以应用不同的层级,为unstack()
函数传入表示层级的编号或名称,即可对相应层级进行操作,如下所示:
import pandas as pd
import numpy as np
dframe = pd.DataFrame(np.arange(9).reshape(3,3),
index=['white', 'black', 'red'],
columns=['ball', 'pen', 'pencil'])
ser = dframe.stack()
print(ser.unstack(0))
print('------------')
print(ser.unstack(1))
输出结果如下:
长格式向宽格式旋转
如果数据来自仪器的读数,或是通过迭代计算得到的,或是由人工输入的一系列元素组成,该类数据集的特点是各列都有数据项,每列后面的数据常常会跟前面的有所重复,并且这类数据常常为列表形式,可以把它称作长格式或栈格式,如下所示:
import pandas as pd
import numpy as np
dframe = pd.DataFrame({'color':['white', 'white', 'white', 'red', 'red', 'red', 'black', 'black', 'black'],
'item':['ball', 'pen', 'mug', 'ball', 'pen', 'mug', 'ball', 'pen', 'mug'],
'value': np.random.rand(9)})
print(dframe)
输出结果如下:
因为一些字段具有多样性和重复性,这种格式的数据可读性比较差,出了长格式,还有一种把数据调整为列表形式的宽格式。这种模式可读性强,占用空间比较少,一般而言,用它存储效率也更高。
Pandas 提供了能够把长格式DataFrame转换成宽格式的pivot()
函数,它以用作键的一列或多列作为参数,如下所示:
import pandas as pd
import numpy as np
longframe = pd.DataFrame({'color':['white', 'white', 'white', 'red', 'red', 'red', 'black', 'black', 'black'],
'item':['ball', 'pen', 'mug', 'ball', 'pen', 'mug', 'ball', 'pen', 'mug'],
'value': np.random.rand(9)})
print(longframe)
print('------------')
wideframe = longframe.pivot('color', 'item')
print(wideframe)
输出结果如下:
如上所示,宽格式的DataFrame对象更加紧凑,可读性也更强。