在所有列上 apply() 自定义函数提高效率

2024-04-24

我应用这个功能

def calculate_recency_for_one_column(column: pd.Series) -> int:
    """Returns the inverse position of the last non-zero value in a pd.Series of numerics.
    If the last value is non-zero, returns 1. If all values are non-zero, returns 0."""
    non_zero_values_of_col = column[column.astype(bool)]
    if non_zero_values_of_col.empty:
        return 0
    return len(column) - non_zero_values_of_col.index[-1]

到此示例数据帧的所有列

df = pd.DataFrame(np.random.binomial(n=1, p=0.001, size=[1000000]).reshape((1000,1000)))

by using

df.apply(lambda column: calculate_recency_for_one_column(column),axis=0)

结果是:

0      436
1        0
2      624
3        0
      ... 
996    155
997    715
998    442
999    163
Length: 1000, dtype: int64

一切工作正常,但我的程序必须经常执行此操作,因此我需要一个更有效的替代方案。有人知道如何让它更快吗?我认为calculate_recency_for_one_column()是足够有效的,并且df.apply()具有最大的改进潜力。这里作为基准(100 次):

>> timeit.timeit(lambda: df.apply(lambda column: calculate_recency_for_one_column(column),axis=0), number=100)
14.700050864834338

Update

穆斯塔法的回答:

>> timeit.timeit(lambda: pd.Series(np.where(df.eq(0).all(), 0, len(df) - df[::-1].idxmax())), number=100)
0.8847485752776265

帕杜的回答:

>> timeit.timeit(lambda: df.apply(calculate_recency_for_one_column_numpy, raw=True, axis=0), number=100)
0.8892530500888824

您可以不将列视为Series对象但作为numpy数组。为此,只需指定raw=True中的参数apply方法。还需要稍微改变一下原来的功能。

import time

import numpy as np
import pandas as pd


def calculate_recency_for_one_column(column: np.ndarray) -> int:
    """Returns the inverse position of the last non-zero value in a np.ndarray of numerics.
    If the last value is non-zero, returns 1. If all values are non-zero, returns 0."""
    non_zero_values_of_col = np.nonzero(column)[0]
    if not non_zero_values_of_col.any():
        return 0
    return len(column) - non_zero_values_of_col[-1]


df = pd.DataFrame(np.random.binomial(n=1, p=0.001, size=[1000000]).reshape((1000,1000)))


start = time.perf_counter()
res = df.apply(calculate_recency_for_one_column, raw=True)
print(f'time took {time.perf_counter() - start:.3f} s.')
Out:
    0.005 s.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在所有列上 apply() 自定义函数提高效率 的相关文章

  • winpdb 不适用于 python 3.3

    我无法让 rpdb2 与 python 3 3 一起运行 但根据多个来源 这应该是可能的 rpdb2 d myscript py A password should be set to secure debugger client serv
  • 通过pip安装lxml时出错:需要Microsoft Visual C++ 14.0

    我使用的是 Windows 10 机器 最近从 python 2 7 迁移到 3 5 当尝试通过 pip 安装 lxml 时 它会停止并抛出此错误消息 构建 lxml etree 扩展错误 需要 Microsoft Visual C 14
  • SQLAlchemy 闭包表关系定义

    我最近开始使用 SQL Alchemy 开展一个涉及攀岩区域和路线的项目 区域是分层的 因为单个区域可以包含多个区域 而多个区域又可以包含其他区域 路线直接与单个区域关联 但也与该区域的父区域关联 等等 为了实现这一点 我选择使用Bill
  • Pythonic方式逐行读取文件?

    以下两种方法中逐行读取文件的 Pythonic 方法是什么 with open file r as f for line in f print line or with open file r as f for line in f read
  • 使用分组的多列熊猫绘制堆积条形图

    我有两个数据框 我需要获取它们之间的差异 然后在该差异之上绘制其中一个数据框 这是一个最小的例子 import pandas as pd import matplotlib pyplot as plt df1 pd DataFrame 2
  • 使用数据库数据模型生成 SQLAlchemy 模型、架构和 JSON 响应

    将 Flask 和 SQLAlchemy 用于 Python Web 应用程序 我的目标是创建一个系统 在其中我可以 从现有 PostgreSQL 数据库导入数据模型 并将它们映射到相应 SQLAlchemy 模型中的字段 使用这些 SQL
  • 如何从numpy数组中获取两个最小值

    我想从数组中取出两个最小值x 但是当我使用np where A B np where x x min 0 1 我收到此错误 ValueError 需要超过 1 个值才能解压 我该如何修复这个错误 我需要在数组中按升序排列数字吗 您可以使用n
  • Pandas 无法读取使用 h5py 创建的 hdf5 文件

    当我尝试读取使用 h5py 创建的 HDF5 格式文件时 出现 pandas 错误 我想知道我是否只是做错了什么 import h5py import numpy as np import pandas as pd h5 file h5py
  • 向 list.extend() 传递不可迭代对象

    我正在创建一个公共方法来允许调用者将值写入设备 例如将其称为 write vals 由于这些值将实时输入 因此我希望通过允许用户输入列表或单个值来简化用户的生活 具体取决于他们需要写入的值的数量 例如 write to device 1 2
  • 如何开始使用“scipy”

    我之前安装过 Python 3 4 2 和 3 5 2 在这两种情况下 我都可以在 Idle 中涉足编写和测试代码 这给了我两个窗口 一个用于代码的 运行 窗口 一个用于交互和测试的 Shell 窗口 输出 抱歉 不确定术语是否正确 现在我
  • Flask 无法识别两个 URL 参数

    我正在尝试将两个参数发送到使用 Flask 路由的 URL If I do curl i http 127 0 0 1 5000 api journeys count startStationName Hansard 20Mews 20Sh
  • 如何在 Django 中创建多选框?

    我正在尝试创建多选框字段来自姜戈选择 2 https github com applegrew django select2库如下图所示 我使用了下一个代码 但它返回简单的选择多个小部件 我想我忘了补充一些东西 我的错误在哪里 有人可以告诉
  • 是否可以将 SpaCy 安装到 Raspberry Pi 4 Raspbian Buster

    我一整天都在安装 SpaCy sudo pip install U spacy Looking in indexes https pypi org simple https www piwheels org simple Collectin
  • python 中打印变量和字符串

    好吧 我知道如何打印变量和字符串 但是我如何打印类似 我的字符串 card price 的内容 它是我的变量 我的意思是 这是我的代码 print I have and here I would like to print my varia
  • 在 matplotlib 中添加新的导航模式

    我正在编写一个 wx matplotlib 应用程序 并且在向 matplotlib 导航工具栏添加新工具时遇到相当大的困难 基本上我想添加选择工具 选取框 套索等 以切换受控子图的鼠标模式 到目前为止 我还没有找到任何功能可以让我轻松地做
  • 是否可以使用 Google BERT 来计算两个文本文档之间的相似度?

    是否可以使用 Google BERT 来计算两个文本文档之间的相似度 据我了解 BERT 的输入应该是有限大小的句子 一些作品使用 BERT 来计算句子的相似度 例如 https github com AndriyMulyar semant
  • 从 C++ 检索 Python 类型

    这个问题实际上是以下两个问题的延伸 如何在 Python 中实现 C 类 以供 C 调用 https stackoverflow com questions 9040669 how can i implement a c class in
  • mpld3图,注释问题

    我正在使用 mpld3 在 Intranet 网站上显示图形 我正在使用将图形保存到字典并使用 mpld3 js 在客户端渲染它的选项 除非我想使用注释 否则该图呈现良好 这些显然是抵消的 我不明白为什么 因为即使我将偏移量设置为 0 0
  • 将 sudo 与 Python 脚本结合使用

    我正在尝试编写一个小脚本来在每次执行脚本时安装 VirtualBox 共享文件夹 我想用Python 来做这件事 因为我正在尝试学习它来编写脚本 问题是我需要特权才能启动挂载命令 我可以将脚本作为 sudo 运行 但我更喜欢它自己创建 su
  • 无法比较类型“ndarray(dtype=int64)”和“str”

    Example of data that I want to replace 数据具有以下属性 购买 V 高 高 中 低 维持 V 高 高 中 低 门 2 3 4 5 更多 2 4人以上 lug boot 小 中 大 安全性低 中高 这就是

随机推荐