前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >pandas中数据框的reshape操作

pandas中数据框的reshape操作

作者头像
生信修炼手册
发布2020-07-02 15:01:20
4.4K0
发布2020-07-02 15:01:20
举报
文章被收录于专栏:生信修炼手册生信修炼手册

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

1. stack

stack函数的基本用法如下

代码语言:javascript
复制
>>> 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进行转换,用法如下

代码语言:javascript
复制
>>> 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,下标-1和1对应同一个值
>>> 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参数进行控制,示例如下

代码语言:javascript
复制
# 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正好相反,是其逆函数,实现由长到宽的转换,用法如下

代码语言:javascript
复制
>>> 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,用法如下

代码语言:javascript
复制
>>> 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函数则可以通过参数指定需要转换的列,用法如下

代码语言:javascript
复制
>>> 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参数,可以指定不进行转换的列,用法如下

代码语言:javascript
复制
>>> 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参数,指定需要进行转换的列,用法如下

代码语言:javascript
复制
>>> 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参数进行自定义,用法如下

代码语言:javascript
复制
>>> 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个参数指定需要对应的列,用法如下

代码语言:javascript
复制
>>> 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实现由长到宽的转换。

·end·

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 生信修炼手册 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档