Cle*_*leb 3 python performance dataframe pandas
我有一个这样的数据框
import pandas as pd
df = pd.DataFrame({'A':list('bbcddee'), 'B': list('klmnnoi')})
A B
0 b k
1 b l
2 c m
3 d n
4 d n
5 e o
6 e i
Run Code Online (Sandbox Code Playgroud)
我想从列中创建一个字典A并B使用例如
dict(zip(df.A, df.B))
Run Code Online (Sandbox Code Playgroud)
在此之前,我想检查一下 in 中的每个值是否A仅映射到 中的一个值B;如果不是,则应抛出错误;上面的情况并非如此,因为b映射到kandl并且e映射到oand i。
接近它的一种方法是:
df[df.groupby('A', sort=False)['B'].transform(lambda x: len(set(x))) > 1]
Run Code Online (Sandbox Code Playgroud)
返回
A B
0 b k
1 b l
5 e o
6 e i
Run Code Online (Sandbox Code Playgroud)
但是,这需要一个lambda可能会使其变慢的。有没有人看到加快速度的选项?
你可以groupby用nunique获得的“B”属于在“A”的每个唯一值的唯一值如何。
df.groupby('A').B.nunique()
#A
#b 2
#c 1
#d 1
#e 2
#Name: B, dtype: int64
Run Code Online (Sandbox Code Playgroud)
因此,您可以检查其中是否有超过 1 个映射:
df.groupby('A').B.nunique().gt(1).any()
#True
Run Code Online (Sandbox Code Playgroud)
以上在概念上与您提出的没有什么不同。但是,如果您能够使用已“优化”的内置 groupby 操作,而不是需要循环的慢速 lambda,则通常会获得重大的性能提升。我们可以看到,随着 DataFrame 变大,lambda 会变慢近 100 倍,这在开始需要几秒钟来计算时是一个大问题。
import perfplot
import pandas as pd
import numpy as np
def gb_lambda(df):
return df.groupby('A')['B'].apply(lambda x: len(set(x))).gt(1)
def gb_nunique(df):
return df.groupby('A').B.nunique().gt(1)
perfplot.show(
setup=lambda n: pd.DataFrame({'A': np.random.randint(0, n//2, n),
'B': np.random.randint(0, n//2, n)}),
kernels=[
lambda df: gb_lambda(df),
lambda df: gb_nunique(df),
],
labels=['groupby with lambda', 'Groupby.nunique'],
n_range=[2 ** k for k in range(2,18)],
equality_check=np.allclose,
xlabel='~len(df)'
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
56 次 |
| 最近记录: |