Pandas:枢轴与pivot_table的区别。为什么只有 pivot_table 有效?
Pandas: Difference between pivot and pivot_table. Why is only pivot_table working?
我有以下数据框。
df.head(30)
struct_id resNum score_type_name score_value
0 4294967297 1 omega 0.064840
1 4294967297 1 fa_dun 2.185618
2 4294967297 1 fa_dun_dev 0.000027
3 4294967297 1 fa_dun_semi 2.185591
4 4294967297 1 ref -1.191180
5 4294967297 2 rama -0.795161
6 4294967297 2 omega 0.222345
7 4294967297 2 fa_dun 1.378923
8 4294967297 2 fa_dun_dev 0.028560
9 4294967297 2 fa_dun_rot 1.350362
10 4294967297 2 p_aa_pp -0.442467
11 4294967297 2 ref 0.249477
12 4294967297 3 rama 0.267443
13 4294967297 3 omega 0.005106
14 4294967297 3 fa_dun 0.020352
15 4294967297 3 fa_dun_dev 0.025507
16 4294967297 3 fa_dun_rot -0.005156
17 4294967297 3 p_aa_pp -0.096847
18 4294967297 3 ref 0.979644
19 4294967297 4 rama -1.403292
20 4294967297 4 omega 0.212160
21 4294967297 4 fa_dun 4.218029
22 4294967297 4 fa_dun_dev 0.003712
23 4294967297 4 fa_dun_semi 4.214317
24 4294967297 4 p_aa_pp -0.462765
25 4294967297 4 ref -1.960940
26 4294967297 5 rama -0.600053
27 4294967297 5 omega 0.061867
28 4294967297 5 fa_dun 3.663050
29 4294967297 5 fa_dun_dev 0.004953
根据数据透视文档,我应该能够使用数据透视函数在 score_type_name 上重塑它。
df.pivot(columns='score_type_name',values='score_value',index=['struct_id','resNum'])
但是,我得到以下信息。
但是,pivot_table 函数似乎有效:
pivoted = df.pivot_table(columns='score_type_name',
values='score_value',
index=['struct_id','resNum'])
但至少对我而言,它不适合进一步分析。我希望它只将 struct_id、resNum 和 score_type_name 作为列,而不是将 score_type_name 堆叠在其他列的顶部。此外,我希望 struct_id 用于每一行,而不是像 table.
那样聚合在一个连接的行中
所以谁能告诉我如何使用 pivot 获得我想要的漂亮 Dataframe?此外,从文档中,我无法说出为什么 pivot_table 有效而 pivot 无效。如果我查看 pivot 的第一个示例,它看起来正是我需要的。
P.S。
我针对这个问题做了 post 个问题,但我在演示输出方面做得很差,我删除了它并再次尝试使用 ipython notebook。如果您看到两次,我提前道歉。
Here is the notebook for your full reference
编辑 - 我想要的结果看起来像这样(在 excel 中制作):
StructId resNum pdb_residue_number chain_id name3 fa_dun fa_dun_dev fa_dun_rot fa_dun_semi omega p_aa_pp rama ref
4294967297 1 99 A ASN 2.1856 0.0000 2.1856 0.0648 -1.1912
4294967297 2 100 A MET 1.3789 0.0286 1.3504 0.2223 -0.4425 -0.7952 0.2495
4294967297 3 101 A VAL 0.0204 0.0255 -0.0052 0.0051 -0.0968 0.2674 0.9796
4294967297 4 102 A GLU 4.2180 0.0037 4.2143 0.2122 -0.4628 -1.4033 -1.9609
4294967297 5 103 A GLN 3.6630 0.0050 3.6581 0.0619 -0.2759 -0.6001 -1.5172
4294967297 6 104 A MET 1.5175 0.2206 1.2968 0.0504 -0.3758 -0.7419 0.2495
4294967297 7 105 A HIS 3.6987 0.0184 3.6804 0.0547 0.4019 -0.1489 0.3883
4294967297 8 106 A THR 0.1048 0.0134 0.0914 0.0003 -0.7963 -0.4033 0.2013
4294967297 9 107 A ASP 2.3626 0.0005 2.3620 0.0521 0.1955 -0.3499 -1.6300
4294967297 10 108 A ILE 1.8447 0.0270 1.8176 0.0971 0.1676 -0.4071 1.0806
4294967297 11 109 A ILE 0.1276 0.0092 0.1183 0.0208 -0.4026 -0.0075 1.0806
4294967297 12 110 A SER 0.2921 0.0342 0.2578 0.0342 -0.2426 -1.3930 0.1654
4294967297 13 111 A LEU 0.6483 0.0019 0.6464 0.0845 -0.3565 -0.2356 0.7611
4294967297 14 112 A TRP 2.5965 0.1507 2.4457 0.5143 -0.1370 -0.5373 1.2341
4294967297 15 113 A ASP 2.6448 0.1593 0.0510 -0.5011
我不确定我是否理解,但我会试一试。我通常使用 stack/unstack 而不是 pivot,这个更接近你想要的吗?
df.set_index(['struct_id','resNum','score_type_name']).unstack()
score_value
score_type_name fa_dun fa_dun_dev fa_dun_rot fa_dun_semi omega
struct_id resNum
4294967297 1 2.185618 0.000027 NaN 2.185591 0.064840
2 1.378923 0.028560 1.350362 NaN 0.222345
3 0.020352 0.025507 -0.005156 NaN 0.005106
4 4.218029 0.003712 NaN 4.214317 0.212160
5 3.663050 0.004953 NaN NaN 0.061867
score_type_name p_aa_pp rama ref
struct_id resNum
4294967297 1 NaN NaN -1.191180
2 -0.442467 -0.795161 0.249477
3 -0.096847 0.267443 0.979644
4 -0.462765 -1.403292 -1.960940
5 NaN -0.600053 NaN
我不确定为什么你的枢轴不起作用(在我看来有点像它应该的,但我可能是错的),但它似乎确实起作用(或者至少没有给出错误)如果我离开 'struct_id'。当然,对于 'struct_id'.
有多个不同值的完整数据集,这并不是真正有用的解决方案
df.pivot(columns='score_type_name',values='score_value',index='resNum')
score_type_name fa_dun fa_dun_dev fa_dun_rot fa_dun_semi omega
resNum
1 2.185618 0.000027 NaN 2.185591 0.064840
2 1.378923 0.028560 1.350362 NaN 0.222345
3 0.020352 0.025507 -0.005156 NaN 0.005106
4 4.218029 0.003712 NaN 4.214317 0.212160
5 3.663050 0.004953 NaN NaN 0.061867
score_type_name p_aa_pp rama ref
resNum
1 NaN NaN -1.191180
2 -0.442467 -0.795161 0.249477
3 -0.096847 0.267443 0.979644
4 -0.462765 -1.403292 -1.960940
5 NaN -0.600053 NaN
编辑添加: reset_index()
将从多索引(分层)样式转换为扁平样式。列名中仍然存在一些层次结构,有时摆脱这些的最简单方法就是 df.columns=['var1','var2',...]
尽管如果您进行一些搜索,还有更复杂的方法。
df.set_index(['struct_id','resNum','score_type_name']).unstack().reset_index()
struct_id resNum score_value
score_type_name fa_dun fa_dun_dev fa_dun_rot
0 4294967297 1 2.185618 0.000027 NaN
1 4294967297 2 1.378923 0.028560 1.350362
2 4294967297 3 0.020352 0.025507 -0.005156
3 4294967297 4 4.218029 0.003712 NaN
4 4294967297 5 3.663050 0.004953 NaN
要将您从 pivot_table
调用中获得的数据帧转换为您想要的格式:
pivoted.columns.name=None ## remove the score_type_name
result = pivoted.reset_index() ## puts index columns back into dataframe body
我调试了一下。
DataFrame.pivot()
和DataFrame.pivot_table()
不同。
pivot()
不接受索引列表。
pivot_table()
接受。
在内部,他们都使用 reset_index()
/stack()
/unstack()
来完成工作。
我认为 pivot()
只是简单用法的捷径。
另一个警告:
pivot_table
将只允许数值类型如 "values=",而 pivot
将接受字符串类型如 "values=".
对于仍然对pivot
和pivot_table
之间的区别感兴趣的人来说,主要有两个区别:
pivot_table
是 pivot
的泛化,可以处理一对 pivoted index/column 的重复值。具体来说,您可以使用关键字参数 aggfunc
为 pivot_table
提供聚合函数列表。 pivot_table
的默认aggfunc
是numpy.mean
.
pivot_table
还支持对 pivoted table 的索引和列使用多列。将为您自动生成分层索引。
REF: pivot
and pivot_table
给定的代码片段可能会帮助您进一步扁平化数据框的外观
df.set_index(['struct_id','resNum','score_type_name']).unstack().reset_index()
df.loc[:,['struct_id','resNum','fa_dun','fa_dun_dev','fa_dun_rot']]
在调用 pivot 之前,我们需要确保我们的数据没有 行具有 指定列 的重复值 。
重复给予的枢轴
Index contains duplicate entries, cannot reshape
如果我们不能确保这一点,我们可能不得不使用 pivot_table 方法。
请在下面找到link以获得更详细的解释
pivot()
用于不聚合的透视。因此,它无法处理一对 index/column 的重复值。
由于此处您的 index=['struct_id','resNum']
有多个重复项,因此数据透视表不起作用。
但是,pivot_table
会起作用,因为它会通过聚合来处理重复值。
我有以下数据框。
df.head(30)
struct_id resNum score_type_name score_value
0 4294967297 1 omega 0.064840
1 4294967297 1 fa_dun 2.185618
2 4294967297 1 fa_dun_dev 0.000027
3 4294967297 1 fa_dun_semi 2.185591
4 4294967297 1 ref -1.191180
5 4294967297 2 rama -0.795161
6 4294967297 2 omega 0.222345
7 4294967297 2 fa_dun 1.378923
8 4294967297 2 fa_dun_dev 0.028560
9 4294967297 2 fa_dun_rot 1.350362
10 4294967297 2 p_aa_pp -0.442467
11 4294967297 2 ref 0.249477
12 4294967297 3 rama 0.267443
13 4294967297 3 omega 0.005106
14 4294967297 3 fa_dun 0.020352
15 4294967297 3 fa_dun_dev 0.025507
16 4294967297 3 fa_dun_rot -0.005156
17 4294967297 3 p_aa_pp -0.096847
18 4294967297 3 ref 0.979644
19 4294967297 4 rama -1.403292
20 4294967297 4 omega 0.212160
21 4294967297 4 fa_dun 4.218029
22 4294967297 4 fa_dun_dev 0.003712
23 4294967297 4 fa_dun_semi 4.214317
24 4294967297 4 p_aa_pp -0.462765
25 4294967297 4 ref -1.960940
26 4294967297 5 rama -0.600053
27 4294967297 5 omega 0.061867
28 4294967297 5 fa_dun 3.663050
29 4294967297 5 fa_dun_dev 0.004953
根据数据透视文档,我应该能够使用数据透视函数在 score_type_name 上重塑它。
df.pivot(columns='score_type_name',values='score_value',index=['struct_id','resNum'])
但是,我得到以下信息。
但是,pivot_table 函数似乎有效:
pivoted = df.pivot_table(columns='score_type_name',
values='score_value',
index=['struct_id','resNum'])
但至少对我而言,它不适合进一步分析。我希望它只将 struct_id、resNum 和 score_type_name 作为列,而不是将 score_type_name 堆叠在其他列的顶部。此外,我希望 struct_id 用于每一行,而不是像 table.
那样聚合在一个连接的行中所以谁能告诉我如何使用 pivot 获得我想要的漂亮 Dataframe?此外,从文档中,我无法说出为什么 pivot_table 有效而 pivot 无效。如果我查看 pivot 的第一个示例,它看起来正是我需要的。
P.S。 我针对这个问题做了 post 个问题,但我在演示输出方面做得很差,我删除了它并再次尝试使用 ipython notebook。如果您看到两次,我提前道歉。
Here is the notebook for your full reference
编辑 - 我想要的结果看起来像这样(在 excel 中制作):
StructId resNum pdb_residue_number chain_id name3 fa_dun fa_dun_dev fa_dun_rot fa_dun_semi omega p_aa_pp rama ref
4294967297 1 99 A ASN 2.1856 0.0000 2.1856 0.0648 -1.1912
4294967297 2 100 A MET 1.3789 0.0286 1.3504 0.2223 -0.4425 -0.7952 0.2495
4294967297 3 101 A VAL 0.0204 0.0255 -0.0052 0.0051 -0.0968 0.2674 0.9796
4294967297 4 102 A GLU 4.2180 0.0037 4.2143 0.2122 -0.4628 -1.4033 -1.9609
4294967297 5 103 A GLN 3.6630 0.0050 3.6581 0.0619 -0.2759 -0.6001 -1.5172
4294967297 6 104 A MET 1.5175 0.2206 1.2968 0.0504 -0.3758 -0.7419 0.2495
4294967297 7 105 A HIS 3.6987 0.0184 3.6804 0.0547 0.4019 -0.1489 0.3883
4294967297 8 106 A THR 0.1048 0.0134 0.0914 0.0003 -0.7963 -0.4033 0.2013
4294967297 9 107 A ASP 2.3626 0.0005 2.3620 0.0521 0.1955 -0.3499 -1.6300
4294967297 10 108 A ILE 1.8447 0.0270 1.8176 0.0971 0.1676 -0.4071 1.0806
4294967297 11 109 A ILE 0.1276 0.0092 0.1183 0.0208 -0.4026 -0.0075 1.0806
4294967297 12 110 A SER 0.2921 0.0342 0.2578 0.0342 -0.2426 -1.3930 0.1654
4294967297 13 111 A LEU 0.6483 0.0019 0.6464 0.0845 -0.3565 -0.2356 0.7611
4294967297 14 112 A TRP 2.5965 0.1507 2.4457 0.5143 -0.1370 -0.5373 1.2341
4294967297 15 113 A ASP 2.6448 0.1593 0.0510 -0.5011
我不确定我是否理解,但我会试一试。我通常使用 stack/unstack 而不是 pivot,这个更接近你想要的吗?
df.set_index(['struct_id','resNum','score_type_name']).unstack()
score_value
score_type_name fa_dun fa_dun_dev fa_dun_rot fa_dun_semi omega
struct_id resNum
4294967297 1 2.185618 0.000027 NaN 2.185591 0.064840
2 1.378923 0.028560 1.350362 NaN 0.222345
3 0.020352 0.025507 -0.005156 NaN 0.005106
4 4.218029 0.003712 NaN 4.214317 0.212160
5 3.663050 0.004953 NaN NaN 0.061867
score_type_name p_aa_pp rama ref
struct_id resNum
4294967297 1 NaN NaN -1.191180
2 -0.442467 -0.795161 0.249477
3 -0.096847 0.267443 0.979644
4 -0.462765 -1.403292 -1.960940
5 NaN -0.600053 NaN
我不确定为什么你的枢轴不起作用(在我看来有点像它应该的,但我可能是错的),但它似乎确实起作用(或者至少没有给出错误)如果我离开 'struct_id'。当然,对于 'struct_id'.
有多个不同值的完整数据集,这并不是真正有用的解决方案df.pivot(columns='score_type_name',values='score_value',index='resNum')
score_type_name fa_dun fa_dun_dev fa_dun_rot fa_dun_semi omega
resNum
1 2.185618 0.000027 NaN 2.185591 0.064840
2 1.378923 0.028560 1.350362 NaN 0.222345
3 0.020352 0.025507 -0.005156 NaN 0.005106
4 4.218029 0.003712 NaN 4.214317 0.212160
5 3.663050 0.004953 NaN NaN 0.061867
score_type_name p_aa_pp rama ref
resNum
1 NaN NaN -1.191180
2 -0.442467 -0.795161 0.249477
3 -0.096847 0.267443 0.979644
4 -0.462765 -1.403292 -1.960940
5 NaN -0.600053 NaN
编辑添加: reset_index()
将从多索引(分层)样式转换为扁平样式。列名中仍然存在一些层次结构,有时摆脱这些的最简单方法就是 df.columns=['var1','var2',...]
尽管如果您进行一些搜索,还有更复杂的方法。
df.set_index(['struct_id','resNum','score_type_name']).unstack().reset_index()
struct_id resNum score_value
score_type_name fa_dun fa_dun_dev fa_dun_rot
0 4294967297 1 2.185618 0.000027 NaN
1 4294967297 2 1.378923 0.028560 1.350362
2 4294967297 3 0.020352 0.025507 -0.005156
3 4294967297 4 4.218029 0.003712 NaN
4 4294967297 5 3.663050 0.004953 NaN
要将您从 pivot_table
调用中获得的数据帧转换为您想要的格式:
pivoted.columns.name=None ## remove the score_type_name
result = pivoted.reset_index() ## puts index columns back into dataframe body
我调试了一下。
DataFrame.pivot()
和DataFrame.pivot_table()
不同。pivot()
不接受索引列表。pivot_table()
接受。
在内部,他们都使用 reset_index()
/stack()
/unstack()
来完成工作。
pivot()
只是简单用法的捷径。
另一个警告:
pivot_table
将只允许数值类型如 "values=",而 pivot
将接受字符串类型如 "values=".
对于仍然对pivot
和pivot_table
之间的区别感兴趣的人来说,主要有两个区别:
pivot_table
是pivot
的泛化,可以处理一对 pivoted index/column 的重复值。具体来说,您可以使用关键字参数aggfunc
为pivot_table
提供聚合函数列表。pivot_table
的默认aggfunc
是numpy.mean
.pivot_table
还支持对 pivoted table 的索引和列使用多列。将为您自动生成分层索引。
REF: pivot
and pivot_table
给定的代码片段可能会帮助您进一步扁平化数据框的外观
df.set_index(['struct_id','resNum','score_type_name']).unstack().reset_index()
df.loc[:,['struct_id','resNum','fa_dun','fa_dun_dev','fa_dun_rot']]
在调用 pivot 之前,我们需要确保我们的数据没有 行具有 指定列 的重复值 。
重复给予的枢轴
Index contains duplicate entries, cannot reshape
如果我们不能确保这一点,我们可能不得不使用 pivot_table 方法。
请在下面找到link以获得更详细的解释
pivot()
用于不聚合的透视。因此,它无法处理一对 index/column 的重复值。
由于此处您的 index=['struct_id','resNum']
有多个重复项,因此数据透视表不起作用。
但是,pivot_table
会起作用,因为它会通过聚合来处理重复值。