Python之数据重塑
文章目录
重塑层次化索引
Pandas中重塑层次化索引的操作主要是stack()方法和unstack()方法,前者是将数据的列“旋转”成行,后者是将数据的行“旋转”成列。
stack(self, level=-1, dropna=True)
上述方法中部分参数表示的含义如下:
- level:表示操作内层索引。若设为0,表示操作外层索引,默认为-1
- dropna:表示是否将旋转后的缺失值删除,若设为True,则表示自动过滤缺失值,设置False则相反
unstack(self, level=-1, fill_value=None)
上述方法中部分参数表示的含义如下:
- level:表示操作内层索引。若设为0,表示操作外层索引,默认为-1
- fill_value:若产生了缺失值,则可以设置这个参数用来替换NaN
对于单层索引的DataFrame类对象
stack()方法
测试对象:
df1:
A B
a A0 B0
b A1 B1
代码:
import numpy as np
df1 = pd.DataFrame({'A': ['A0', 'A1'],
'B': ['B0', 'B1']},
index=['a', 'b'])
df2 = pd.DataFrame(np.arange(8).reshape(2, 4),
columns=[['A', 'A', 'B', 'B'],
['A0', 'A1', 'B0', 'B1']])
result = df1.stack()
print("df1.stack():\n", result)
输出结果:
df1.stack():
a A A0
B B0
b A A1
B B1
dtype: object
从输出结果看出,result对象具有两层行索引。
具有两层行索引而不再具有列索引的对象到底是DataFrame对象还是Series对象呢?
我们使用type()函数来查看result的类型,与df1做对比
type(df1):
<class 'pandas.core.frame.DataFrame'>
type(result):
<class 'pandas.core.series.Series'>
从输出结果可以看出,DataFrame对象已经被转换成了一个Series对象。
unstack()方法
尝试将result对象重塑成df1,先将result.unstack()的结果保存在ans对象里
代码:
ans = result.unstack()
print("ans:\n", ans)
输出结果:
ans:
A B
a A0 B0
b A1 B1
使用type()函数查看ans的类型,然后将其与df1作比较
代码:
print("type(ans):\n", type(ans))
print("ans == df1?", ans == df1)
输出结果:
type(ans):
<class 'pandas.core.frame.DataFrame'>
ans == df1?
A B
a True True
b True True
由上可知,unstack()方法是stack()方法的逆操作,可以将重塑的Series对象“恢复原样”,转变成原来的DataFrame对象。
对于多层索引的DataFrame类对象
测试对象:
df2:
A B
A0 A1 A0 A1
0 0 1 2 3
1 4 5 6 7
辨析操作内层索引与外层索引的区别
代码:
df2 = pd.DataFrame(np.arange(8).reshape(2, 4),
columns=[['A', 'A', 'B', 'B'],
['A0', 'A1', 'A0', 'A1']])
result1 = df2.stack() # 操作内层索引
result2 = df2.stack(level=0) # 操作外层索引
print("df2.stack():\n", result1)
print("df2.stack(level=0):\n", result2)
输出结果:
df2.stack():
A B
0 A0 0 2
A1 1 3
1 A0 4 6
A1 5 7
df2.stack(level=0):
A0 A1
0 A 0 1
B 2 3
1 A 4 5
B 6 7
查看多层索引对象转换后的类型
代码:
print("type(result1):\n", type(result1))
print("type(result2):\n", type(result2))
输出结果:
type(result1):
<class 'pandas.core.frame.DataFrame'>
type(result2):
<class 'pandas.core.frame.DataFrame'>
对于多层索引来讲,即使将外层行(列)索引或者内层行()列索引转换为列(行)索引,也不过是多层变单层,只要行和列两个方向仍然同时至少有单层索引存在,DataFrmae对象转换后就仍为DataFrame对象。
轴向旋转——pivot()方法
pivot()会根据给定的行索引或列索引重新组织一个DataFrame对象
pivot(self, index=None, columns=None, values=None)
上述方法中部分参数表示的含义如下:
- index:用于创建新DataFrame对象的行索引 。如果未设置,则使用原DataFrame对象的索引。
- columns:用于创建新DataFrame对象的列索引 。如果未设置,则使用原DataFrame对象的索引。
- values:用于填充新DataFrame对象中的值。
代码:
df3 = pd.DataFrame({'A': ['A0', 'A0', 'A1', 'A1'],
'B': ['B0', 'B1', 'B0', 'B1'],
'C': ['C0', 'C1', 'C2', 'C3']})
print("df3:\n", df3)
print("df3.pivot(index='A', columns='B', values='C'):\n",
df3.pivot(index='A', columns='B', values='C'))
输出结果:
df3:
A B C
0 A0 B0 C0
1 A0 B1 C1
2 A1 B0 C2
3 A1 B1 C3
df3.pivot(index='A', columns='B', values='C'):
B B0 B1
A
A0 C0 C1
A1 C2 C3
下一篇: Leecode刷题java之重塑矩阵