数据框的长宽转换对于熟悉R语言的朋友而言,应该不会陌生。使用ggplot2画图时,最常用的数据处理就是长宽转换了。在pandas中,也提供了数据框的长宽转换功能,有以下几种实现方式 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,下标-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参数进行控制,示例如下 # 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 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实现由长到宽的转换。
|