为什么“df.lookup”比“df.min”慢?

2024-03-20

我想通过使用来减少一些时间lookup after idxmin,而不是调用min and idxmin。在我看来,第一个应该更有效,因为在第二个中需要搜索两次值(一次搜索最小值,另一次搜索最小值的索引 - 即 2 倍 O(NxM)),而在首先,搜索索引 (O(NxM)),然后使用索引来定位值 (O(N))

请检查这个问题 https://stackoverflow.com/questions/51931137/is-there-a-vectorized-way-to-access-values-of-column-explicitely-indicated-in-an这样你就可以了解我的推理的背景和更多细节。

结果开始出乎意料,所以我继续进行了一些测试:

我使用了 100000 行 x 10 列的数据框(添加更多行结果会变得更糟):

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randint(0,100,size=(100000, 10)), columns=[f'option_{x}' for x in range(1,11)]).reset_index()
df['min_column'] = df.filter(like='option').idxmin(1)

然后我做了一些计时:

%timeit -n 100 df.filter(like='option').min(1)
# 12.2 ms ± 599 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit -n 100 df.lookup(df.index, df['min_column'])
# 46.9 ms ± 526 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

请注意,即使min_columns被预先计算为lookup,结果比单纯寻找最小值差 4 倍。

其他尺寸对比:

RowsxCols    min        lookup
100000x10    12.2ms     46.9ms
1000000x10   162ms      682ms
10000x1000   173ms      220ms
1000x10000   295ms      7.97ms

从上表中可以看出,正如预期的那样,通过添加行 (1000000x10),结果并没有得到任何改善,并且在添加更多列 (10000x1000) 时,结果也只是略有改善。这种追赶是有道理的,但在我看来,它应该更大,索引应该比搜索更快(参见更新的 numpy 结果),并且只有在极端情况下(几乎不切实际,例如 1000x10000)我才开始看到优势。

这种行为有什么解释吗?

UPDATE:

我用 numpy 测试了这个,得到了预期的行为:

vals = np.random.randint(0,10,size=(100000, 10))
%timeit -n 100 np.min(vals, axis=1)
2.83 ms ± 235 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

idx_min = np.argmin(vals, axis=1)
%timeit -n 100 vals[np.arange(len(idx_min)), idx_min]
1.63 ms ± 243 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

比较结果(numpy):

RowsxCols    min        indexing using []
100000x10    2.83ms     1.63ms
1000000x10   24.6ms     15.4ms
100000x100   14.5ms     3.38ms
10000x1000   11.1ms   0.377ms

如果你看一下查找函数的源代码实现,它看起来效率不是很高。源代码可以在这里找到:

http://github.com/pandas-dev/pandas/blob/v0.23.4/pandas/core/frame.py#L3435-L3484 http://github.com/pandas-dev/pandas/blob/v0.23.4/pandas/core/frame.py#L3435-L3484

特别是,在主要的 if-else 条件体中,它确实

if not self._is_mixed_type or n > thresh:
        values = self.values
        ridx = self.index.get_indexer(row_labels)
        cidx = self.columns.get_indexer(col_labels)
        if (ridx == -1).any():
            raise KeyError('One or more row labels was not found')
        if (cidx == -1).any():
            raise KeyError('One or more column labels was not found')
        flat_index = ridx * len(self.columns) + cidx
        result = values.flat[flat_index]

result = np.empty(n, dtype='O')
for i, (r, c) in enumerate(zip(row_labels, col_labels)):
        result[i] = self._get_value(r, c)

我不确定 if 情况的详细实现,但您可能想在大量行和大量列的情况下尝试此操作,并且您可能会从查找函数中获得更好的结果。

您可能应该尝试定义自己的查找表,这样您就可以准确地知道运行时,而不是使用此查找函数

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么“df.lookup”比“df.min”慢? 的相关文章

随机推荐

  • 为什么 android:fullBackupOnly 默认值是 false?

    In https developer android com guide topics manifest application element https developer android com guide topics manife
  • 如何避免链接多个 AsyncTask 调用?

    我必须对 Web 服务进行多次调用 但每个步骤都使用上一步中的值 因此现在我有一个巨大的 AsyncTasks 链 每个 AsyncTask 都在上一步的 AsyncTask 的 onPostExecute 中执行 这非常非常难看 而且很难
  • Perl DBIx::Class 可以覆盖从数据库检索列的方式吗?

    直到今天我才使用过 DBIx Class 所以我对它完全陌生 我不确定这是否可能 但基本上我的 SQLite 数据库中有一个表 其中有一个时间戳列 时间戳列的默认值为 CURRENT TIMESTAMP SQLite 将其存储在 GMT 时
  • 总是收到“消息”:“未经身份验证。” - Laravel 护照

    我一整天都找到了很多教程 我的设置与所有基本教程完全相同 目前 我可以访问http localhost oauth token成功地将令牌返回给我 之后 我使用 ARC Advanced Rest Client 来进行调用我自己的 api
  • 如何在SQL中获取2个表中不匹配的行?

    我有两个 SQL Server 表 CHANNELS SUBSCRIBERS 我想从中获取行CHANNELS不存在于SUBSCRIBERS在某种条件下 我尝试过INNER和OUTER LEFT JOIN但这对我不起作用 他们都给了我相同的答
  • 将一组字符串转换为 byte[] 数组

    我正在尝试将一组字符串转换为 byte 数组 首先 我执行以下操作将字节数组转换为字符串 public String convertByte byte msg String str for int i 0 i lt msg length i
  • 如何在iPhone中获取DNS服务器IP

    我尝试通过以下方式获取 etc resolv conf 打开 etc resolv conf 0644 但它返回 1并且errno是2这意味着 没有这样的文件 我能做些什么 您无法访问应用程序沙箱之外的文件
  • 反应本机错误 RCTJSONStringify() 遇到以下错误:JSON 写入中的类型无效 (NSURL)

    我正在尝试使用反应本机fbsdk在我的反应本机应用程序中 直到昨天为止都运行良好 但是 今天它给出了一个奇怪的错误RCTJSONStringify 遇到以下错误 JSON 写入 NSURL 中的类型无效 RN v0 42 0 这是我的代码
  • 从 dll 内的函数返回时堆损坏

    我有一个具有如下原型的函数 void function std string str 这个函数在另一个加载和使用该 dll 的程序的主函数中被调用 function some string value here 从该函数返回时 我收到堆损坏
  • 使用 Nokogiri 解析大型 HTML 文件

    我正在尝试解析与 Nokogiri 但不幸的是我无法从页面获取所有项目 我的简单测试代码是 require open uri require nokogiri html Nokogiri HTML open http www pro med
  • bash 中的视频方向检测

    我需要检测视频是以纵向还是横向模式录制的 然后以脚本方式将其转换为正确的方向 if v orient landscape then ffmpeg i file mp4 vf transpose 1 file ogv else ffmpeg
  • ABAP中调用方法的不同方式

    抱歉这个基本的 ABAP 问题 ABAP中调用方法有哪些不同的方式 他们的 官方 名字是什么 我听说过执行 方法调用和内部 内联方法调用 执行使用PERFORM关键字和方法调用CALL METHOD语法 我猜 但什么是 内部 或 内联方法调
  • 如何使用 std::cin 读取 bool

    我是 C 新手 我想知道函数 cin 在布尔数据的情况下如何工作 比方说 bool a cin gt gt a 我知道如果我给出 0 或 1 我的数据 a 将是 true 或 false 但是如果我给出另一个整数甚至一个字符串会发生什么 我
  • 允许所有用户进行临时分发查询

    我正在使用 AD Hoc 分布式查询将数据从 MS SQL Server 2008 传输到 MS Access 该过程使用单个 SQL 语句启动 INSERT INTO OpenDataSource Microsoft Jet OLEDB
  • Arrays.stream(array_name).sum() 比迭代方法慢吗?

    我正在编写一个 leetcode 问题 https oj leetcode com problems gas station https oj leetcode com problems gas station 使用Java 8 我的解决方
  • 是否可以将Spring Data JPA中的@Lock和@Modifying @Query与Hibernate结合起来?

    我有一个 Lock注解与 Modifying Query一起使用时出现问题和查询本身执行更新语句 我的测试设置如下所示 Spring Boot 启动器 1 5 3 RELEASE 休眠 5 2 10 Final Spring Data JP
  • Git 将存储库镜像到特定分支

    我们公司尝试将一个github项目fork到我们自己的git服务器上 然后我们可以在上面添加我们自己的功能 我们只想签出一个特定的分支 并将所有分支和标签保留到该分支 然后复制 镜像 到我们的 git 服务器 在您的服务器上创建存储库 在其
  • Pandas:迭代 DataFrame 列表并将每个数据框导出到 Excel 工作表

    尝试自学编码以自动化工作中一些繁琐的任务 对于任何无意的无知 我深表歉意 我在 pandas python 3 x 中创建了数据框 我想将每个数据框打印到不同的 Excel 工作表中 这是我的 2 个数据帧 它工作完美 但我想缩放它以循环遍
  • 使用新的 YouTube API v3 解析 YouTube 订阅者计数

    我想使用新的 API v3 从我的 YouTube 频道获取订阅者数量 我在这里为 youtube 创建了一个 Google API 应用程序 谷歌 API 控制台 https code google com apis console 我有
  • 为什么“df.lookup”比“df.min”慢?

    我想通过使用来减少一些时间lookup after idxmin 而不是调用min and idxmin 在我看来 第一个应该更有效 因为在第二个中需要搜索两次值 一次搜索最小值 另一次搜索最小值的索引 即 2 倍 O NxM 而在首先 搜