pandas中数据框的reshape操作

数据框的长宽转换对于熟悉R语言的朋友而言,应该不会陌生。使用ggplot2画图时,最常用的数据处理就是长宽转换了。在pandas中,也提供了数据框的长宽转换功能,有以下几种实现方式
1. stack

stack函数的基本用法如下

>>> import pandas as pd
>>> import numpy as np
>>> a = pd.DataFrame(np.random.rand(4, 2),index=['G1', 'G2', 'G3', 'G4'], columns=['A', 'B'])
>>> a
           A B
G1 0.353756 0.349514
G2 0.958544 0.085568
G3 0.041538 0.910649
G4 0.230912 0.500152

>>> a.stack()
G1 A 0.353756
  B 0.349514
G2 A 0.958544
  B 0.085568
G3 A 0.041538
  B 0.910649
G4 A 0.230912
  B 0.500152
dtype: float64

用法很简单,将所有的列标签转换为行标签,将对应的值转换为新的数据框中的某一列,从而实现了数据框由宽到长的转换。

对于列标签为multiindex的情况,还可以通过level和dropna两个参数来控制其转换的行为。level参数指定multiindex的下标,默认为-1,使用最后一个index进行转换,用法如下

>>> multi_index = pd.MultiIndex.from_tuples([('groupA', 'A'),('groupB', 'B')])
>>> a = pd.DataFrame(np.random.rand(4, 2),index=['G1', 'G2', 'G3', 'G4'], columns=multi_index)
>>> a
  groupA   groupB
    A       B
G1 0.546331  0.808608
G2 0.013087  0.237910
G3 0.122436  0.174456
G4 0.329789  0.285292

# 默认用最后一个列标签,(A, B)
>>> a.stack()
   groupA  groupB
G1 A 0.546331 NaN
  B NaN    0.808608
G2 A 0.013087 NaN
  B NaN    0.237910
G3 A 0.122436 NaN
  B NaN    0.174456
G4 A 0.329789 NaN
  B NaN    0.285292

# 列标签的长度为2,下标-11对应同一个值
>>> a.stack(level=1)
   groupA  groupB
G1 A 0.546331 NaN
  B NaN    0.808608
G2 A 0.013087 NaN
  B NaN    0.237910
G3 A 0.122436 NaN
  B NaN    0.174456
G4 A 0.329789 NaN
  B NaN    0.285292

# 0表示使用第一个列标签(groupA, groupB)
>>> a.stack(level=0)
       A    B
G1 groupA 0.546331 NaN
  groupB NaN    0.808608
G2 groupA 0.013087 NaN
  groupB NaN    0.237910
G3 groupA 0.122436 NaN
  groupB NaN    0.174456
G4 groupA 0.329789 NaN
  groupB NaN    0.285292


# 也可以用列表的形式,同时指定多个标签
>>> a.stack(level=[0,1])
G1 groupA A 0.546331
  groupB B 0.808608
G2 groupA A 0.013087
  groupB B 0.237910
G3 groupA A 0.122436
  groupB B 0.174456
G4 groupA A 0.329789
  groupB B 0.285292
dtype: float64

指定了多个列标签时,全部转换会出现NaN值,默认情况下,会去除NaN值,这个行为有dropna参数进行控制,示例如下

# dropna默认值为True, 去除NaN
>>> a.stack(level=[0,1], dropna=True)
G1 groupA A 0.546331
  groupB B 0.808608
G2 groupA A 0.013087
  groupB B 0.237910
G3 groupA A 0.122436
  groupB B 0.174456
G4 groupA A 0.329789
  groupB B 0.285292
dtype: float64

# dropna=False, 不去除NaN
>>> a.stack(level=[0,1], dropna=False)
G1 groupA A 0.546331
       B NaN
  groupB A NaN
       B 0.808608
G2 groupA A 0.013087
       B NaN
  groupB A NaN
       B 0.237910
G3 groupA A 0.122436
       B NaN
  groupB A NaN
       B 0.174456
G4 groupA A 0.329789
       B NaN
  groupB A NaN
       B 0.285292
dtype: float64
2. unstack

unstack和stack正好相反,是其逆函数,实现由长到宽的转换,用法如下

>>> index = pd.MultiIndex.from_tuples([('G1','A',),('G1','B'), ('G2','A'),('G2','B')])
>>> index
MultiIndex([('G1', 'A'),
      ('G1', 'B'),
      ('G2', 'A'),
      ('G2', 'B')],
           )

>>> a = pd.Series(np.random.rand(4),index=index)
>>> a
G1 A 0.466375
  B 0.844325
G2 A 0.188146
  B 0.177540
dtype: float64
>>> a.unstack()
    A        B
G1 0.466375  0.844325
G2 0.188146  0.177540

通过level参数指定行标签的下标,默认值为-1,用法如下

>>> a.unstack(level=0)
    G1    G2
A 0.466375 0.188146
B 0.844325 0.177540
>>> a.unstack(level=1)
     A    B
G1 0.466375 0.844325
G2 0.188146 0.177540
>>> a.unstack(level=-1)
     A    B
G1 0.466375 0.844325
G2 0.188146 0.177540

3. melt

melt函数和stack函数的作用类似,但是更加灵活。stack会将所有的列标签都进行转换,而melt函数则可以通过参数指定需要转换的列,用法如下

>>> df = pd.DataFrame({'A': {0: 'a', 1: 'b', 2: 'c'},
... 'B': {0: 1, 1: 3, 2: 5},
... 'C': {0: 2, 1: 4, 2: 6}})
>>>
>>> df
 A B C
0 a 1 2
1 b 3 4
2 c 5 6


>>> df.melt()
 variable value
0 A a
1 A b
2 A c
3 B 1
4 B 3
5 B 5
6 C 2
7 C 4
8 C 6

默认行为和stack函数类似,所有的列标签都进行转换。不同之处,在于转换后的列标签不是以index的形式出现,而是作为数据框中的variable列。

通过id_vars参数,可以指定不进行转换的列,用法如下

>>> df.melt(id_vars=['A'])
   A variable value
0 a B 1
1 b B 3
2 c B 5
3 a C 2
4 b C 4
5 c C 6

通过value_vars参数,指定需要进行转换的列,用法如下

>>> df.melt(id_vars=['A'], value_vars=['B'])
 A variable value
0 a B 1
1 b B 3
2 c B 5

>>> df.melt(id_vars=['A'], value_vars=['B','C'])
 A variable value
0 a B 1
1 b B 3
2 c B 5
3 a C 2
4 b C 4
5 c C 6

默认新生成的数据框,列名都是variable和value,可以通过var_name和value_name参数进行自定义,用法如下

>>> df.melt(id_vars=['A'], var_name='custom_var', value_name='custom_value')
   A custom_var custom_value
0 a B 1
1 b B 3
2 c B 5
3 a C 2
4 b C 4
5 c C 6

4. pivot

pivot函数的作用和unstack类似,实现数据框由长到宽的转换。相比unstack函数,pivot更加灵活,通过指定index,columns, values3个参数指定需要对应的列,用法如下

>>> df = pd.DataFrame({'foo': ['one', 'one', 'one', 'two', 'two',
...                            'two'],
...                    'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
...                    'baz': [1, 2, 3, 4, 5, 6],
...                    'zoo': ['x', 'y', 'z', 'q', 'w', 't']})
>>>
>>> df
   foo bar baz zoo
0  one A 1   x
1  one B 2   y
2  one C 3   z
3  two A 4   q
4  two B 5   w
5  two C 6   t
>>> df.pivot(index='foo', columns='bar', values='baz')
bar A B C
foo
one 1  2  3
two 4  5  6

 

通过以上4个函数就可以轻松实现数据框的长宽转换,其中stack和melt实现数据框由宽到长的转换,unstack和pivot实现由长到宽的转换。

生物信息学

R语言基础教程:多种方法安装R包

2020-6-26 11:49:04

生物信息学

ArchR如何克服scATAC-seq数据的稀疏性?

2020-6-26 20:56:30

声明 本网部分文章源于互联网,转载出于传递更多信息和学习之目的,并不意味着赞同其观点。
如转载稿涉及版权等问题,请立即联系管理员,我们会予以修改、删除相关文章,请留言反馈
When your legal rights are being violated, please send an email to: sci666net@qq.com
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索