gpt4 book ai didi

python - Pandas 在用户定义的函数中使用 Numpy Vectorization 而不是使用 loops/lambda.apply()

转载 作者:太空宇宙 更新时间:2023-11-03 23:51:13 25 4
gpt4 key购买 nike

ytho

目标:对于供应商中的每个单元格:我想检查供应商名称中的每个单词是否都存在于名称数据库中。即 Adam 和 Smith 必须同时存在才能使 IsPerson = TRUE

我知道我可以使用 lambda.apply() 和其他方式来做到这一点,但它们都是基于循环的。我想让它尽可能快和高效,因为我有 120 万行。我听说过 Numpy Vectorization,但不确定当我需要对每个单元格的各个内容运行一些例程时如何使用它。谢谢

最佳答案

不幸的是,如果在 numpy/pandas 中使用字符串,那么在幕后总是有循环。

想法是创建 DataFrame 由空格分割,前向填充最后的值,通过 isin 过滤并最后测试每行是否所有 True :

df1['IsPerson'] = (df1['Vendor'].str.split(expand=True)
.ffill(axis=1)
.isin(df2['Persons'].tolist())
.all(axis=1))

集合的解决方案:

s = set(df2['Persons'])
df1['IsPerson'] = ~df1['Vendor'].map(lambda x: s.isdisjoint(x.split()))

性能

取决于两个数据帧的长度、唯一值的数量和匹配值的数量。所以在真实数据中应该是不同的。

np.random.seed(123)

N = 100000
L = list('abcdefghijklmno ')

df1 = pd.DataFrame({'Vendor': [''.join(x) for x in np.random.choice(L, (N, 5))]})
df2 = pd.DataFrame({'Persons': [''.join(x) for x in np.random.choice(L, (N * 10, 5))]})

In [133]: %%timeit
...: s = set(df2['Persons'])
...: df1['IsPerson1'] = ~df1['Vendor'].map(lambda x: s.isdisjoint(x.split()))
...:
470 ms ± 7.02 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [134]: %%timeit
...: df1['IsPerson2'] = (df1['Vendor'].str.split(expand=True)
...: .ffill(axis=1)
...: .isin(df2['Persons'].tolist())
...: .all(axis=1))
...:
858 ms ± 18.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

关于python - Pandas 在用户定义的函数中使用 Numpy Vectorization 而不是使用 loops/lambda.apply(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59318438/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com