当前位置: 首页 > 面试题库 >

Pandas DataFrame搜索是线性时间还是恒定时间?

漆雕和昶
2023-03-14
问题内容

我有一个df超过15000行的数据框对象,例如:

anime_id          name              genre    rating
1234      Kimi no nawa    Romance, Comedy     9.31
5678       Stiens;Gate             Sci-fi     8.92

我试图找到具有特定anime_id的行。

a_id = "5678"
temp = (df.query("anime_id == "+a_id).genre)

我只是想知道此搜索是在固定时间(如字典)还是线性时间(如列表)中完成的。


问题答案:

这是一个非常有趣的问题!

我认为这取决于以下几个方面:

按索引访问单行( 索引已排序且唯一 )应具有运行时O(m),其中m << n_rows

按索引访问单行( 索引不是唯一的并且未排序 )应该具有运行时O(n_rows)

通过索引访问单行( 索引不是唯一的,并且排序 )应该有运行O(m)在那里m < n_rows

通过布尔索引访问行(独立于索引)应具有运行时 O(n_rows)

演示:

索引是排序且唯一的:

In [49]: df = pd.DataFrame(np.random.rand(10**5,6), columns=list('abcdef'))

In [50]: %timeit df.loc[random.randint(0, 10**4)]
The slowest run took 27.65 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 331 µs per loop

In [51]: %timeit df.iloc[random.randint(0, 10**4)]
1000 loops, best of 3: 275 µs per loop

In [52]: %timeit df.query("a > 0.9")
100 loops, best of 3: 7.84 ms per loop

In [53]: %timeit df.loc[df.a > 0.9]
100 loops, best of 3: 2.96 ms per loop

索引未排序且也不唯一:

In [54]: df = pd.DataFrame(np.random.rand(10**5,6), columns=list('abcdef'), index=np.random.randint(0, 10000, 10**5))

In [55]: %timeit df.loc[random.randint(0, 10**4)]
100 loops, best of 3: 12.3 ms per loop

In [56]: %timeit df.iloc[random.randint(0, 10**4)]
1000 loops, best of 3: 262 µs per loop

In [57]: %timeit df.query("a > 0.9")
100 loops, best of 3: 7.78 ms per loop

In [58]: %timeit df.loc[df.a > 0.9]
100 loops, best of 3: 2.93 ms per loop

索引不是唯一的,并且进行了排序

In [64]: df = pd.DataFrame(np.random.rand(10**5,6), columns=list('abcdef'), index=np.random.randint(0, 10000, 10**5)).sort_index()

In [65]: df.index.is_monotonic_increasing
Out[65]: True

In [66]: %timeit df.loc[random.randint(0, 10**4)]
The slowest run took 9.70 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 478 µs per loop

In [67]: %timeit df.iloc[random.randint(0, 10**4)]
1000 loops, best of 3: 262 µs per loop

In [68]: %timeit df.query("a > 0.9")
100 loops, best of 3: 7.81 ms per loop

In [69]: %timeit df.loc[df.a > 0.9]
100 loops, best of 3: 2.95 ms per loop


 类似资料:
  • 问题内容: 此处通常建议添加索引,以解决性能问题。 (我只在说阅读和查询,我们都知道索引会使写入变慢)。 多年来,我已经在DB2和MSSQL上尝试了很多方法,结果总是令人失望。 我的发现是,无论索引有多“明显”,它都会使事情变得更好。事实证明,查询优化器更智能,而我的明智选择的索引几乎总是使事情变得更糟。 我应该指出,我的经验主要与小型表(<100‘000行)有关。 谁能提供一些切实可行的索引选择

  • 完全创建四叉树后,为什么比较操作(用于对象的冲突检测)需要线性的时间?节点按区域/象限递归地拆分,搜索将向下扫描树,删除不在搜索坐标内的路径,最终在冲突节点的范围内找到或没有找到目标节点。每个操作都在比较一个划分的分区,这看起来像时间,而不是。

  • 我理解线性探测中的问题,即由于后续的索引,会出现元素簇。但是我不明白这句话

  • 问题内容: 通常,一些答案提到给定的解决方案是 线性的 ,或者另一个是 二次的 。 如何发挥作用/识别什么? 有人能为像我这样仍然不认识的人解释这种最简单的方法吗? 问题答案: 当所需时间随所涉及元素的数量线性增加时,该方法是线性的。例如,用于打印数组元素的for循环大致是线性的: 因为如果我们打印range(100)而不是range(10),则运行它所需的时间要长10倍。您会经常看到写为O(N)

  • 问题内容: 您将使用哪种方法确定代表2 ^ x的位是1还是0? 问题答案: 我会用: (您也许可以用更少的括号摆脱掉,但我永远不记得按位运算的优先级。)

  • 考虑到JMH的默认用法,我想确定JMH的测量基于哪种时间类型:CPU时间还是挂钟。 我试着调查JMH的官方样本(https://openjdk.java.net/projects/code-tools/jmh/),教程(在Jenkov、Baeldung、Mykong和其他网站),但未能准确地找到这些信息(我承认我可能错过了一些关于基准测试的文档或一般信息)。 例如,在样本35中(https://h