欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python之数据重塑

程序员文章站 2024-02-28 19:29:40
...


重塑层次化索引

Pandas中重塑层次化索引的操作主要是stack()方法和unstack()方法,前者是将数据的列“旋转”成行,后者是将数据的行“旋转”成列。

stack(self, level=-1, dropna=True)

上述方法中部分参数表示的含义如下:

  1. level:表示操作内层索引。若设为0,表示操作外层索引,默认为-1
  2. dropna:表示是否将旋转后的缺失值删除,若设为True,则表示自动过滤缺失值,设置False则相反

unstack(self, level=-1, fill_value=None)

上述方法中部分参数表示的含义如下:

  1. level:表示操作内层索引。若设为0,表示操作外层索引,默认为-1
  2. 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)

上述方法中部分参数表示的含义如下:

  1. index:用于创建新DataFrame对象的行索引 。如果未设置,则使用原DataFrame对象的索引。
  2. columns:用于创建新DataFrame对象的列索引 。如果未设置,则使用原DataFrame对象的索引。
  3. 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