简介

使用Pandas的pivot方法可以将DF进行旋转变换,本文将会详细讲解pivot的秘密。

使用Pivot

pivot用来重组DF,使用指定的index,columns和values来对现有的DF进行重构。

看一个Pivot的例子:

通过pivot变化,新的DF使用foo中的值作为index,使用bar的值作为columns,zoo作为对应的value。

再看一个时间变化的例子:

In [1]: df
Out[1]:
date variable value
0 2000-01-03 A 0.469112
1 2000-01-04 A -0.282863
2 2000-01-05 A -1.509059
3 2000-01-03 B -1.135632
4 2000-01-04 B 1.212112
5 2000-01-05 B -0.173215
6 2000-01-03 C 0.119209
7 2000-01-04 C -1.044236
8 2000-01-05 C -0.861849
9 2000-01-03 D -2.104569
10 2000-01-04 D -0.494929
11 2000-01-05 D 1.071804
In [3]: df.pivot(index='date', columns='variable', values='value')
Out[3]:
variable A B C D
date
2000-01-03 0.469112 -1.135632 0.119209 -2.104569
2000-01-04 -0.282863 1.212112 -1.044236 -0.494929
2000-01-05 -1.509059 -0.173215 -0.861849 1.071804

如果剩余的value,多于一列的话,每一列都会有相应的columns值:

In [4]: df['value2'] = df['value'] * 2

In [5]: pivoted = df.pivot(index='date', columns='variable')

In [6]: pivoted
Out[6]:
value value2
variable A B C D A B C D
date
2000-01-03 0.469112 -1.135632 0.119209 -2.104569 0.938225 -2.271265 0.238417 -4.209138
2000-01-04 -0.282863 1.212112 -1.044236 -0.494929 -0.565727 2.424224 -2.088472 -0.989859
2000-01-05 -1.509059 -0.173215 -0.861849 1.071804 -3.018117 -0.346429 -1.723698 2.143608

通过选择value2,可以得到相应的子集:

In [7]: pivoted['value2']
Out[7]:
variable A B C D
date
2000-01-03 0.938225 -2.271265 0.238417 -4.209138
2000-01-04 -0.565727 2.424224 -2.088472 -0.989859
2000-01-05 -3.018117 -0.346429 -1.723698 2.143608

使用Stack

Stack是对DF进行转换,将列转换为新的内部的index。

上面我们将列A,B转成了index。

unstack是stack的反向操作,是将最内层的index转换为对应的列。

举个具体的例子:

In [8]: tuples = list(zip(*[['bar', 'bar', 'baz', 'baz',
...: 'foo', 'foo', 'qux', 'qux'],
...: ['one', 'two', 'one', 'two',
...: 'one', 'two', 'one', 'two']]))
...: In [9]: index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second']) In [10]: df = pd.DataFrame(np.random.randn(8, 2), index=index, columns=['A', 'B']) In [11]: df2 = df[:4] In [12]: df2
Out[12]:
A B
first second
bar one 0.721555 -0.706771
two -1.039575 0.271860
baz one -0.424972 0.567020
two 0.276232 -1.087401
In [13]: stacked = df2.stack()

In [14]: stacked
Out[14]:
first second
bar one A 0.721555
B -0.706771
two A -1.039575
B 0.271860
baz one A -0.424972
B 0.567020
two A 0.276232
B -1.087401
dtype: float64

默认情况下unstack是unstack最后一个index,我们还可以指定特定的index值:

In [15]: stacked.unstack()
Out[15]:
A B
first second
bar one 0.721555 -0.706771
two -1.039575 0.271860
baz one -0.424972 0.567020
two 0.276232 -1.087401 In [16]: stacked.unstack(1)
Out[16]:
second one two
first
bar A 0.721555 -1.039575
B -0.706771 0.271860
baz A -0.424972 0.276232
B 0.567020 -1.087401 In [17]: stacked.unstack(0)
Out[17]:
first bar baz
second
one A 0.721555 -0.424972
B -0.706771 0.567020
two A -1.039575 0.276232
B 0.271860 -1.087401

默认情况下stack只会stack一个level,还可以传入多个level:

In [23]: columns = pd.MultiIndex.from_tuples([
....: ('A', 'cat', 'long'), ('B', 'cat', 'long'),
....: ('A', 'dog', 'short'), ('B', 'dog', 'short')],
....: names=['exp', 'animal', 'hair_length']
....: )
....: In [24]: df = pd.DataFrame(np.random.randn(4, 4), columns=columns) In [25]: df
Out[25]:
exp A B A B
animal cat cat dog dog
hair_length long long short short
0 1.075770 -0.109050 1.643563 -1.469388
1 0.357021 -0.674600 -1.776904 -0.968914
2 -1.294524 0.413738 0.276662 -0.472035
3 -0.013960 -0.362543 -0.006154 -0.923061 In [26]: df.stack(level=['animal', 'hair_length'])
Out[26]:
exp A B
animal hair_length
0 cat long 1.075770 -0.109050
dog short 1.643563 -1.469388
1 cat long 0.357021 -0.674600
dog short -1.776904 -0.968914
2 cat long -1.294524 0.413738
dog short 0.276662 -0.472035
3 cat long -0.013960 -0.362543
dog short -0.006154 -0.923061

上面等价于:

In [27]: df.stack(level=[1, 2])

使用melt

melt指定特定的列作为标志变量,其他的列被转换为行的数据。并放置在新的两个列:variable和value中。

上面例子中我们指定了两列first和last,这两列是不变的,height和weight被变换成为行数据。

举个例子:

In [41]: cheese = pd.DataFrame({'first': ['John', 'Mary'],
....: 'last': ['Doe', 'Bo'],
....: 'height': [5.5, 6.0],
....: 'weight': [130, 150]})
....: In [42]: cheese
Out[42]:
first last height weight
0 John Doe 5.5 130
1 Mary Bo 6.0 150 In [43]: cheese.melt(id_vars=['first', 'last'])
Out[43]:
first last variable value
0 John Doe height 5.5
1 Mary Bo height 6.0
2 John Doe weight 130.0
3 Mary Bo weight 150.0 In [44]: cheese.melt(id_vars=['first', 'last'], var_name='quantity')
Out[44]:
first last quantity value
0 John Doe height 5.5
1 Mary Bo height 6.0
2 John Doe weight 130.0
3 Mary Bo weight 150.0

使用Pivot tables

虽然Pivot可以进行DF的轴转置,Pandas还提供了 pivot_table() 在转置的同时可以进行数值的统计。

pivot_table() 接收下面的参数:

data: 一个df对象

values:一列或者多列待聚合的数据。

Index: index的分组对象

Columns: 列的分组对象

Aggfunc: 聚合的方法。

先创建一个df:

In [59]: import datetime

In [60]: df = pd.DataFrame({'A': ['one', 'one', 'two', 'three'] * 6,
....: 'B': ['A', 'B', 'C'] * 8,
....: 'C': ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'] * 4,
....: 'D': np.random.randn(24),
....: 'E': np.random.randn(24),
....: 'F': [datetime.datetime(2013, i, 1) for i in range(1, 13)]
....: + [datetime.datetime(2013, i, 15) for i in range(1, 13)]})
....: In [61]: df
Out[61]:
A B C D E F
0 one A foo 0.341734 -0.317441 2013-01-01
1 one B foo 0.959726 -1.236269 2013-02-01
2 two C foo -1.110336 0.896171 2013-03-01
3 three A bar -0.619976 -0.487602 2013-04-01
4 one B bar 0.149748 -0.082240 2013-05-01
.. ... .. ... ... ... ...
19 three B foo 0.690579 -2.213588 2013-08-15
20 one C foo 0.995761 1.063327 2013-09-15
21 one A bar 2.396780 1.266143 2013-10-15
22 two B bar 0.014871 0.299368 2013-11-15
23 three C bar 3.357427 -0.863838 2013-12-15 [24 rows x 6 columns]

下面是几个聚合的例子:

In [62]: pd.pivot_table(df, values='D', index=['A', 'B'], columns=['C'])
Out[62]:
C bar foo
A B
one A 1.120915 -0.514058
B -0.338421 0.002759
C -0.538846 0.699535
three A -1.181568 NaN
B NaN 0.433512
C 0.588783 NaN
two A NaN 1.000985
B 0.158248 NaN
C NaN 0.176180 In [63]: pd.pivot_table(df, values='D', index=['B'], columns=['A', 'C'], aggfunc=np.sum)
Out[63]:
A one three two
C bar foo bar foo bar foo
B
A 2.241830 -1.028115 -2.363137 NaN NaN 2.001971
B -0.676843 0.005518 NaN 0.867024 0.316495 NaN
C -1.077692 1.399070 1.177566 NaN NaN 0.352360 In [64]: pd.pivot_table(df, values=['D', 'E'], index=['B'], columns=['A', 'C'],
....: aggfunc=np.sum)
....:
Out[64]:
D E
A one three two one three two
C bar foo bar foo bar foo bar foo bar foo bar foo
B
A 2.241830 -1.028115 -2.363137 NaN NaN 2.001971 2.786113 -0.043211 1.922577 NaN NaN 0.128491
B -0.676843 0.005518 NaN 0.867024 0.316495 NaN 1.368280 -1.103384 NaN -2.128743 -0.194294 NaN
C -1.077692 1.399070 1.177566 NaN NaN 0.352360 -1.976883 1.495717 -0.263660 NaN NaN 0.872482

添加margins=True会添加一个All列,表示对所有的列进行聚合:

In [69]: df.pivot_table(index=['A', 'B'], columns='C', margins=True, aggfunc=np.std)
Out[69]:
D E
C bar foo All bar foo All
A B
one A 1.804346 1.210272 1.569879 0.179483 0.418374 0.858005
B 0.690376 1.353355 0.898998 1.083825 0.968138 1.101401
C 0.273641 0.418926 0.771139 1.689271 0.446140 1.422136
three A 0.794212 NaN 0.794212 2.049040 NaN 2.049040
B NaN 0.363548 0.363548 NaN 1.625237 1.625237
C 3.915454 NaN 3.915454 1.035215 NaN 1.035215
two A NaN 0.442998 0.442998 NaN 0.447104 0.447104
B 0.202765 NaN 0.202765 0.560757 NaN 0.560757
C NaN 1.819408 1.819408 NaN 0.650439 0.650439
All 1.556686 0.952552 1.246608 1.250924 0.899904 1.059389

使用crosstab

Crosstab 用来统计表格中元素的出现次数。

In [70]: foo, bar, dull, shiny, one, two = 'foo', 'bar', 'dull', 'shiny', 'one', 'two'

In [71]: a = np.array([foo, foo, bar, bar, foo, foo], dtype=object)

In [72]: b = np.array([one, one, two, one, two, one], dtype=object)

In [73]: c = np.array([dull, dull, shiny, dull, dull, shiny], dtype=object)

In [74]: pd.crosstab(a, [b, c], rownames=['a'], colnames=['b', 'c'])
Out[74]:
b one two
c dull shiny dull shiny
a
bar 1 0 0 1
foo 2 1 1 0

crosstab可以接收两个Series:

In [75]: df = pd.DataFrame({'A': [1, 2, 2, 2, 2], 'B': [3, 3, 4, 4, 4],
....: 'C': [1, 1, np.nan, 1, 1]})
....: In [76]: df
Out[76]:
A B C
0 1 3 1.0
1 2 3 1.0
2 2 4 NaN
3 2 4 1.0
4 2 4 1.0 In [77]: pd.crosstab(df['A'], df['B'])
Out[77]:
B 3 4
A
1 1 0
2 1 3

还可以使用normalize来指定比例值:

In [82]: pd.crosstab(df['A'], df['B'], normalize=True)
Out[82]:
B 3 4
A
1 0.2 0.0
2 0.2 0.6

还可以normalize行或者列:

In [83]: pd.crosstab(df['A'], df['B'], normalize='columns')
Out[83]:
B 3 4
A
1 0.5 0.0
2 0.5 1.0

可以指定聚合方法:

In [84]: pd.crosstab(df['A'], df['B'], values=df['C'], aggfunc=np.sum)
Out[84]:
B 3 4
A
1 1.0 NaN
2 1.0 2.0

get_dummies

get_dummies可以将DF中的一列转换成为k列的0和1组合:

df = pd.DataFrame({'key': list('bbacab'), 'data1': range(6)})

df
Out[9]:
data1 key
0 0 b
1 1 b
2 2 a
3 3 c
4 4 a
5 5 b pd.get_dummies(df['key'])
Out[10]:
a b c
0 0 1 0
1 0 1 0
2 1 0 0
3 0 0 1
4 1 0 0
5 0 1 0

get_dummies 和 cut 可以进行结合用来统计范围内的元素:

In [95]: values = np.random.randn(10)

In [96]: values
Out[96]:
array([ 0.4082, -1.0481, -0.0257, -0.9884, 0.0941, 1.2627, 1.29 ,
0.0824, -0.0558, 0.5366]) In [97]: bins = [0, 0.2, 0.4, 0.6, 0.8, 1] In [98]: pd.get_dummies(pd.cut(values, bins))
Out[98]:
(0.0, 0.2] (0.2, 0.4] (0.4, 0.6] (0.6, 0.8] (0.8, 1.0]
0 0 0 1 0 0
1 0 0 0 0 0
2 0 0 0 0 0
3 0 0 0 0 0
4 1 0 0 0 0
5 0 0 0 0 0
6 0 0 0 0 0
7 1 0 0 0 0
8 0 0 0 0 0
9 0 0 1 0 0

get_dummies还可以接受一个DF参数:

In [99]: df = pd.DataFrame({'A': ['a', 'b', 'a'], 'B': ['c', 'c', 'b'],
....: 'C': [1, 2, 3]})
....: In [100]: pd.get_dummies(df)
Out[100]:
C A_a A_b B_b B_c
0 1 1 0 0 1
1 2 0 1 0 1
2 3 1 0 1 0

本文已收录于 http://www.flydean.com/05-python-pandas-reshaping-pivot/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

Pandas高级教程之:Dataframe的重排和旋转的更多相关文章

  1. Pandas高级教程之:Dataframe的合并

    目录 简介 使用concat 使用append 使用merge 使用join 覆盖数据 简介 Pandas提供了很多合并Series和Dataframe的强大的功能,通过这些功能可以方便的进行数据分析 ...

  2. Pandas高级教程之:GroupBy用法

    Pandas高级教程之:GroupBy用法 目录 简介 分割数据 多index get_group dropna groups属性 index的层级 group的遍历 聚合操作 通用聚合方法 同时使用 ...

  3. Pandas高级教程之:category数据类型

    目录 简介 创建category 使用Series创建 使用DF创建 创建控制 转换为原始类型 categories的操作 获取category的属性 重命名categories 使用add_cate ...

  4. Pandas高级教程之:处理text数据

    目录 简介 创建text的DF String 的方法 columns的String操作 分割和替换String String的连接 使用 .str来index extract extractall c ...

  5. Pandas高级教程之:处理缺失数据

    目录 简介 NaN的例子 整数类型的缺失值 Datetimes 类型的缺失值 None 和 np.nan 的转换 缺失值的计算 使用fillna填充NaN数据 使用dropna删除包含NA的数据 插值 ...

  6. Pandas高级教程之:plot画图详解

    目录 简介 基础画图 其他图像 bar stacked bar barh Histograms box Area Scatter Hexagonal bin Pie 在画图中处理NaN数据 其他作图工 ...

  7. Pandas高级教程之:统计方法

    目录 简介 变动百分百 Covariance协方差 Correlation相关系数 rank等级 简介 数据分析中经常会用到很多统计类的方法,本文将会介绍Pandas中使用到的统计方法. 变动百分百 ...

  8. Pandas高级教程之:window操作

    目录 简介 滚动窗口 Center window Weighted window 加权窗口 扩展窗口 指数加权窗口 简介 在数据统计中,经常需要进行一些范围操作,这些范围我们可以称之为一个window ...

  9. Pandas高级教程之:稀疏数据结构

    目录 简介 Spare data的例子 SparseArray SparseDtype Sparse的属性 Sparse的计算 SparseSeries 和 SparseDataFrame 简介 如果 ...

  10. Pandas高级教程之:自定义选项

    目录 简介 常用选项 get/set 选项 经常使用的选项 最大展示行数 超出数据展示 最大列的宽度 显示精度 零转换的门槛 列头的对齐方向 简介 pandas有一个option系统可以控制panda ...

随机推荐

  1. node版本管理工具nvm的安装及使用

    一.什么是nvm nvm是一个node版本管理工具. 由于不同项目依赖的node版本可能不同,所以在维护多个项目时通常需要使用不同的node版本,这时候用nvm来切换不同的node版本就很方便. 官方 ...

  2. 内存管理(二)之别小看了Tagged-Pointer关键时刻起到大作用

    本文主要研究Tagged Pointer技术,针对该技术需要解决的问题.以及在实际应用中的价值做一些简单的探讨. 如果你想要更进一步,去挖掘Tagged Pointer是如何实现的,可以参考Frida ...

  3. book 电子书转换 在线工具

    https://convertio.co/download/911d3a3f39db0b2e39ed6e3c8acb31f6be786a/ Convertio

  4. C++ STL 容器-string类型

    C++ STL 第一部分-容器 STL的介绍 C++的STL分为六大部分 容器分为 容器的概念 容器内元素的条件 1.必须可以复制copy或者搬移move,包括条件是在拷贝和搬移的过程中不存在副作用. ...

  5. 3、dubbo核心用法

    https://dubbo.apache.org/zh/docs/v2.7/user/examples/preflight-check/ 1.启动时检查 在启动时检查依赖的服务是否可用 Dubbo 缺 ...

  6. CPNtools协议建模安全分析---实例(三)

    对于复杂的系统的建模或者协议的建模,各种颜色集的定义以及变量的声明很重要,要区分明确,对于函数行业进程的定义更加复杂.CPN对协议的描述只适合简单逻辑性的协议分析,如果协议包括复杂的算法,那么CPN就 ...

  7. .net中最简单的http请求调用(比如调用chatgpt的openAI接口)

    支持.Net Core(2.0及以上)/.Net Framework(4.5及以上),可以部署在Docker, Windows, Linux, Mac. http请求调用是开发中经常会用到的功能,因为 ...

  8. Java GUI swing 可执行程序 jar (java -jar)idea

    创建项目 可以用maven idea设置 into 那个 参考资料 Java 基础 https://www.liaoxuefeng.com/wiki/1252599548343744/12604545 ...

  9. Rust GUI库 egui 的简单应用

    目录 简介 简单示例 创建项目 界面设计 切换主题 自定义字体 自定义图标 经典布局 定义导航变量 实现导航界面 实现导航逻辑 实现主框架布局 调试运行 参考资料 简介 egui(发音为"e ...

  10. PlayBook 详解

    4)Playbook 4.1)Playbook 介绍 PlayBook 与 ad-hoc 相比,是一种完全不同的运用 Ansible 的方式,类似与 Saltstack 的 state 状态文件.ad ...