pandas 在行名称上使用.loc与使用searchsorted

nukf8bse  于 2023-04-28  发布在  其他
关注(0)|答案(1)|浏览(113)

我有一个pandas数据框,其中有一个排序列id。我需要在代码中多次通过id引用数据框中的行。通过pd.searchsorteddf['id']==value来做更快,或者通过df = df.set_index('id')id列作为键,然后用df.loc[[value],:]对其进行切片?或者没有区别,因为它们都有相同的实现?有关其他信息, Dataframe 非常大:大约1e7行。

iecba09b

iecba09b1#

考虑两种情况:
1.您正在搜索的ID存在
1.您访问的页面不存在
在情况1)中,np.searchsorted(df['id'], id)df.index[df['id'] == id]都返回相同的结果。除了,当“id”列排序时,np.searchsorted可以在O中检索答案这是因为searchsorted使用二进制搜索来遍历数组,而不是返回O(N)时间。但这只在“id”排序时有效,否则searchsorted行为不正确。
对于情况2),它变得有点棘手。如果id不存在,searchsorted仍然返回一个结果。它返回“id”在排序数组中存在的位置。因此,您有责任仔细检查该位置的id是否与您正在查找的id匹配。使用相等比较,如果id不存在,则返回结果。索引是假的。
如果要加快查找速度,可以在以下条件下将DataFrame索引设置为“id”:

  1. id已排序(否则会遇到performance warnings
  2. id是唯一的(尽管对于此工作不是关键的)
    1.您需要执行足够多的查找以证明将其设置为索引是正确的
    在这些条件下,“id”将被散列,查找可以是常数时间O(1)操作,可以用df.loc[key]key in df.index完成。
    至于性能,您可以使用%timeit轻松验证性能。
    这两种方法的时间是最简单的方法。
    设置:
import pandas as pd
import numpy as np

np.random.seed(0)

n = 100000
ids = np.random.randint(0, 1000000, size=n)
values = np.random.randn(n)

df = pd.DataFrame({'id': np.sort(ids), 'value': values})

验证正确性:

# pick an id that exists
key = 498044
id = np.searchsorted(df['id'], key)
df.iloc[id]
id       498044.000000
value         0.469857
Name: 50000, dtype: float64
id = df.index[df['id'] == key][0]
df.loc[id]
id       498044.000000
value         0.469857
Name: 50000, dtype: float64

现在,我们计算这些操作的时间:

%%timeit 
key = 498044
id = np.searchsorted(df['id'], key)
df.iloc[id]

%%timeit 
id = df.index[df['id'] == key][0]
df.loc[id]

两个都返回

30.5 µs ± 635 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) # 4X faster
121 µs ± 652 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

相关问题