在SQL中,借助OLAP函数,我们可以一次性计算不同的键,从而提高了SQL性能:
select
B,
C,
D,
count(A) over (partition by B, C, D order by D) as by_BCD.
count(A) over (partition by B, C order by D) as by_BC,
count(A) over (partition by B order by D) as by_B,
count(A) over () as total,
from table;
我们可以在一次熊猫数据帧扫描中执行相同的操作,而不是按数据帧分组3次吗?
Input dataset:
A B C D
1 LZ 0 1
2 LZ 0 1
3 LZ 1 1
4 LZ 1 2
5 LZ 1 2
6 SB 0 1
7 SB 0 1
8 SB 1 1
9 SB 1 2
10 SB 1 2
11 PZ 0 1
Output dataset:
A B C D by_BCD by_BC by_B total
1 LZ 0 1 2 2 5 11
2 LZ 0 1 2 2 5 11
3 LZ 1 1 1 3 5 11
4 LZ 1 2 2 3 5 11
5 LZ 1 2 2 3 5 11
6 SB 0 1 2 2 5 11
7 SB 0 1 2 2 5 11
8 SB 1 1 1 3 5 11
9 SB 1 2 2 3 5 11
10 SB 1 2 2 3 5 11
11 PZ 0 1 1 1 1 11
以下是代码段:
d = {'A': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
'B': ['LZ', 'LZ', 'LZ', 'LZ', 'LZ', 'SB', 'SB', 'SB', 'SB', 'SB', 'PZ'],
'C': [0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0],
'D': [1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 1]}
df = pd.DataFrame(d)
答案 0 :(得分:0)
在上面的评论中,我建议使用Multiindex。
我的假设是,性能损失源于group by语句中的隐式索引。
按照OP所述创建df:
import pandas as pd
d = {'A': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
'B': ['LZ', 'LZ', 'LZ', 'LZ', 'LZ', 'SB', 'SB', 'SB', 'SB', 'SB', 'PZ'],
'C': [0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0],
'D': [1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 1]}
df = pd.DataFrame(d)
排序并创建Multiindex。为了使DataFrame.groupby
的性能更好,排序就足够了。我没有尝试过。
indexed = df.sort_values(['B', 'C', 'D']).set_index(['B', 'C', 'D'])
这将产生:
A
B C D
LZ 0 1 1
1 2
1 1 3
2 4
2 5
PZ 0 1 11
SB 0 1 6
1 7
1 1 8
2 9
2 10
为单行选择计数:
indexed.loc['LZ', 0, 1].count() # 2
分组和计数,例如在“ BC”上方:
indexed.groupby(['B', 'C']).count()
产量:
A
B C
LZ 0 2
1 3
PZ 0 1
SB 0 2
1 3
如上所述,我对性能的假设只是假设。