创建一个列出值的数据透视表
Posted
技术标签:
【中文标题】创建一个列出值的数据透视表【英文标题】:Create a pivot table that lists out values 【发布时间】:2018-03-26 09:34:50 【问题描述】:我需要使用什么 aggfunc 来使用数据透视表生成列表?我尝试使用 str ,但效果不太好。
输入
import pandas as pd
data =
'Test point': [0, 1, 2, 0, 1],
'Experiment': [1, 2, 3, 4, 5]
df = pd.DataFrame(data)
print df
pivot = pd.pivot_table(df, index=['Test point'], values=['Experiment'], aggfunc=len)
print pivot
pivot = pd.pivot_table(df, index=['Test point'], values=['Experiment'], aggfunc=str)
print pivot
输出
Experiment Test point
0 1 0
1 2 1
2 3 2
3 4 0
4 5 1
Experiment
Test point
0 2
1 2
2 1
Experiment
Test point
0 0 1\n3 4\nName: Experiment, dtype: int64
1 1 2\n4 5\nName: Experiment, dtype: int64
2 2 3\nName: Experiment, dtype: int64
期望的输出
Experiment
Test point
0 1, 4
1 2, 5
2 3
【问题讨论】:
【参考方案1】:您可以将list
本身用作函数:
>>> pd.pivot_table(df, index=['Test point'], values=['Experiment'], aggfunc=lambda x:list(x))
Experiment
Test point
0 [1, 4]
1 [2, 5]
2 [3]
【讨论】:
【参考方案2】:使用
In [1830]: pd.pivot_table(df, index=['Test point'], values=['Experiment'],
aggfunc=lambda x: ', '.join(x.astype(str)))
Out[1830]:
Experiment
Test point
0 1, 4
1 2, 5
2 3
或者,groupby
可以。
In [1831]: df.groupby('Test point').agg(
'Experiment': lambda x: x.astype(str).str.cat(sep=', '))
Out[1831]:
Experiment
Test point
0 1, 4
1 2, 5
2 3
但是,如果你想要那么作为列表。
In [1861]: df.groupby('Test point').agg('Experiment': lambda x: x.tolist())
Out[1861]:
Experiment
Test point
0 [1, 4]
1 [2, 5]
2 [3]
x.astype(str).str.cat(sep=', ')
类似于', '.join(x.astype(str))
【讨论】:
【参考方案3】:选项 1str
预转换 + groupby
+ apply
。
您可以预先转换为字符串以简化groupby
调用。
df.assign(Experiment=df.Experiment.astype(str))\
.groupby('Test point').Experiment.apply(', '.join).to_frame('Experiment')
Experiment
Test point
0 1, 4
1 2, 5
2 3
为了速度,对此的修改将涉及就地分配(assign
返回一个副本并且速度较慢):
df.Experiment = df.Experiment.astype(str)
df.groupby('Test point').Experiment.apply(', '.join).to_frame('Experiment')
Experiment
Test point
0 1, 4
1 2, 5
2 3
还有修改原始数据框的缺点。
性能
# Zero's 1st solution
%%timeit
df.groupby('Test point').agg('Experiment': lambda x: x.astype(str).str.cat(sep=', '))
100 loops, best of 3: 3.72 ms per loop
# Zero's second solution
%%timeit
pd.pivot_table(df, index=['Test point'], values=['Experiment'],
aggfunc=lambda x: ', '.join(x.astype(str)))
100 loops, best of 3: 5.17 ms per loop
# proposed in this post
%%timeit -n 1
df.Experiment = df.Experiment.astype(str)
df.groupby('Test point').Experiment.apply(', '.join).to_frame('Experiment')
1 loop, best of 3: 2.02 ms per loop
请注意,.assign
方法只比这慢几毫秒。更大的数据帧应该会看到更大的性能提升。
选项 2groupby
+ agg
:
agg
进行类似的操作:
df.assign(Experiment=df.Experiment.astype(str))\
.groupby('Test point').agg('Experiment' : ', '.join)
Experiment
Test point
0 1, 4
1 2, 5
2 3
并且它的就地版本将与上述相同。
# proposed in this post
%%timeit -n 1
df.Experiment = df.Experiment.astype(str)
df.groupby('Test point').agg('Experiment' : ', '.join)
1 loop, best of 3: 2.21 ms per loop
agg
对于更大的数据帧,速度应该会超过apply
。
【讨论】:
以上是关于创建一个列出值的数据透视表的主要内容,如果未能解决你的问题,请参考以下文章