Pandas DataFrame - 列 whos dtype=='category' 上的聚合导致性能下降

2024-06-26

我使用内存使用量较高的大数据帧,并且我读到,如果更改重复值列上的数据类型,我可以节省大量内存。

我尝试了一下,确实内存使用量下降了 25%,但随后我遇到了我无法理解的性能缓慢问题。

我对 dtype“类别”列进行分组聚合,在更改 dtype 之前大约需要 1 秒,更改后大约需要 1 分钟。

此代码演示了性能下降 2 倍:

import pandas as pd
import random

animals = ['Dog', 'Cat']
days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday','Saturday']

columns_dict = {'animals': [],
                'days': []}

for i in range(1000000):
    columns_dict['animals'].append(animals[random.randint(0, len(animals)-1)])
    columns_dict['days'].append(days[random.randint(0, len(days)-1)])

# df without 'category' dtype
df = pd.DataFrame(columns_dict)

df.info(memory_usage='deep') # will result in memory usage of 95.5 MB

%timeit -n100 df.groupby('days').agg({'animals': 'first'})
# will result in: 100 loops, best of 3: 54.2 ms per loop

# df with 'category' dtype
df2 = df.copy()
df2['animals'] = df2['animals'].astype('category')

df2.info(memory_usage='deep') # will result in memory usage of 50.7 MB

%timeit -n100 df2.groupby('days').agg({'animals': 'first'})
# will result in: 100 loops, best of 3: 111 ms per loop

我试图了解这种缓慢的原因是什么以及是否有办法克服它。

Thanks!


我不确定这种速度下降的原因,但一种解决方法是直接存储类别代码:

df3 = df.copy()
animals = pd.Categorical(df['animals'])
df3['animals'] = animals.codes
df3.groupby('days').agg({'animals': 'first'}).apply(lambda code: animals.categories[code])

它不是最干净的解决方案,因为它需要外部元数据,但它实现了您正在寻找的内存效率和计算速度。深入研究 Pandas 内部所做的事情导致分类速度减慢会很有趣。


编辑:我追查了为什么会发生这种情况......作为first()聚合,熊猫calls np.asarray()在柱子上 https://github.com/pandas-dev/pandas/blob/0.22.x/pandas/core/groupby.py#L1258-L1271。对于分类列,这最终会将列转换回非分类列,从而导致不必要的开销。解决这个问题将是对 pandas 包的有用贡献!

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

Pandas DataFrame - 列 whos dtype=='category' 上的聚合导致性能下降 的相关文章

  • python-polars 通过分隔符将字符串列拆分为许多列

    在 pandas 中 以下代码会将 col1 中的字符串拆分为许多列 有没有办法在极地做到这一点 d col1 a b c d a b c d df pd DataFrame data d df a b c d df col1 str sp
  • pandas to_sql sqlalchemy 与 secure_transport 的连接

    我正在尝试将数据发送到具有 require secure transport ON 的服务器上的 mysql 数据库 当我尝试使用以下代码连接到它时 import pandas as pd import pymysql from sqlal
  • 根据给定列表中的值替换列中的值[重复]

    这个问题在这里已经有答案了 我在数据框中有一列 仅允许定义列表中存在的值 例如 给定列表 l1 1 2 5 6 如果列表中不存在列中的值 我需要将每个值替换为 0 column Expected column 1 1 5 5 2 2 3 0
  • 检查多个 pd.DataFrame 是否相等

    是否有一种 Pythonic 方式 无循环或递归 来检查是否超过两个pd DataFrames 例如 pd DataFrames 列表 彼此相等吗 就像是 all x equals dfs 0 for x in dfs with dfs数据
  • 从 pandas 数据框中删除 NaN 值并重塑表[重复]

    这个问题在这里已经有答案了 给定一个包含列的数据框NaNs 如何转换数据框以删除所有NaN从列中 示例数据框 import pandas as pd import numpy as np dataframe from list of lis
  • 验证 PyPI Python 包的完整性

    最近有一些消息传出恶意库已上传到 Python Package Index PyPI 请参阅 PyPI 上的恶意库 https www bleepingcomputer com news security ten malicious lib
  • “foreach”并行循环返回 s

    我正在尝试并行处理多个列表项 我的目标是 根据每列的值运行一些标签函数 然后返回带有节点名称 列名称和处理后的标签的数据帧 使用普通的 for 循环 工作流程可以正常工作 但是 当我尝试在 foreach 循环中执行相同的操作时 返回的结果
  • 在 pandas 数据框中进行 groupby 后滚动前 3 个月的唯一计数

    以下是数据框 Date Name data 01 01 2017 Alpha A 02 01 2017 Alpha A 03 01 2017 Alpha B 01 01 2017 Beta A 01 20 2017 Beta D 03 01
  • 从 r 中的数据帧中删除每第 n 列

    我试图通过删除每第三列来减小数据框的大小 这是我的示例数据框 example data frame x c 1 2 3 4 y c 1 2 3 4 z c 1 2 3 4 w c 1 2 3 4 p c 1 2 3 4 q c 1 2 3
  • pandas 数据框到键值对

    将以下 pandas 数据帧转换为键值对的最佳方法是什么 Before datetime name qty price 2017 11 01 10 20 apple 5 1 2017 11 01 11 20 pear 2 1 5 2017
  • 无法在 Windows 中安装 mysql-python(较新版本)

    I have mysql pythonv1 2 4 在我的机器 Windows 8 上安装得很好 我正在使用Python 2 7 每次尝试升级到 v1 2 5 时 我总是遇到以下错误 从 v1 3 7 开始仍然发生 C Users User
  • 如何在Python多处理中的所有进程之间共享数据?

    我想在给定文章中搜索预定义的关键字列表 如果在文章中找到关键字 则分数加 1 我想使用多重处理 因为预定义的关键字列表非常大 10k 个关键字 文章数量为 100k 我碰到this https stackoverflow com quest
  • 使用 loc 命令替换值

    有一个数据框 我需要replace值高于 512 时为 263 因此 我首先使用此代码行来过滤索引 df loc df Fare gt 512 Fare astype int 这是结果 258 512 679 512 737 512 123
  • 在 Scala Spark 和 PySpark 之间传递 SparkSession

    我的要求是从现有的 PySpark 程序调用 Spark Scala 函数 将 PySpark 程序中创建的 SparkSession 传递给 Scala 函数的最佳方法是什么 我将 scala jar 传递给 Pyspark 如下所示 s
  • Pandas.read_excel:访问主目录

    找到解决方案 尝试使用以下命令访问我的主目录时 我遇到了一些意外行为pandas read excel 我想要访问的文件可以在以下位置找到 users isys orsheridanmeth 这是哪里cd 带我去 我想访问的文件是 work
  • Pandas dataframe.query 方法语法

    问题 我想更好地了解熊猫DataFrame query http pandas pydata org pandas docs stable generated pandas DataFrame query html方法以及以下表达式代表的含
  • 如何计算两个邮政编码之间的距离?

    我有一个美国邮政编码列表 我必须计算所有邮政编码点之间的距离 它是一个 6k 邮政编码长列表 每个实体都有邮政编码 城市 州 纬度 经度 面积和人口 所以 我必须计算所有点之间的距离 即 6000C2 组合 这是我的数据示例 我已经在 SA
  • Python Pandas 全局变量与传递变量

    我正在创建一个 实时 流程 该流程从由 SierraChart 更新的专有格式 OHLCVTBA 文件中获取数据 读取数据并使用生成器创建数据框的代码发布在pastebin上 删除死链接 我已经意识到我的结构 新数据驱动 是错误的 我即将重
  • 使用 SQLAlchemy 查询 Pandas DataFrame 时重命名列

    当您将数据查询到 pandas 数据帧时 有没有办法保留 SqlAlchemy 属性名称 这是我的数据库的简单映射 对于 school 表 我将数据库名称 SchoolDistrict 重命名为较短的 district 我从 DBA 中删除
  • pandas groupby 中两个系列的最大值和最小值

    是否可以从 groupby 中的两个系列中获取最小值和最大值 例如下面的情况 分组时c 我怎样才能得到最小值和最大值a and b同时 df pd DataFrame a 10 20 3 40 55 b 5 14 8 50 60 c x x

随机推荐