Pandas操作期间的进度指示器

2024-05-16 15:31:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我经常对超过1500万行左右的数据帧执行pandas操作,我希望能够访问特定操作的进度指示器。

是否存在基于文本的pandas split apply combine操作进度指示器?

例如,在类似于:

df_users.groupby(['userID', 'requestDate']).apply(feature_rollup)

其中feature_rollup是一个有点复杂的函数,它接受许多DF列并通过各种方法创建新的用户列。对于大型数据帧,这些操作可能需要一段时间,因此我想知道是否有可能在iPython笔记本中使用基于文本的输出来更新我的进度。

到目前为止,我已经尝试了Python的规范循环进度指示器,但是它们没有以任何有意义的方式与panda交互。

我希望在pandas库/文档中有一些我忽略了的东西,可以让人知道拆分应用组合的进度。一个简单的实现可能会查看apply函数在其上工作的数据帧子集的总数,并将进度报告为这些子集的完成部分。

这可能是需要添加到库中的内容吗?


Tags: 数据函数文本pandasdfusers子集feature
3条回答

如果您像我一样需要在Jupyter/ipython笔记本中使用此功能的支持,这里有一个有用的指南和relevant article的源代码:

from tqdm._tqdm_notebook import tqdm_notebook
import pandas as pd
tqdm_notebook.pandas()
df = pd.DataFrame(np.random.randint(0, int(1e8), (10000, 1000)))
df.groupby(0).progress_apply(lambda x: x**2)

注意_tqdm_notebook的import语句中的下划线。正如参考文章所提到的,开发处于后期测试阶段。

修改Jeff的答案(并将其作为可重用函数)。

def logged_apply(g, func, *args, **kwargs):
    step_percentage = 100. / len(g)
    import sys
    sys.stdout.write('apply progress:   0%')
    sys.stdout.flush()

    def logging_decorator(func):
        def wrapper(*args, **kwargs):
            progress = wrapper.count * step_percentage
            sys.stdout.write('\033[D \033[D' * 4 + format(progress, '3.0f') + '%')
            sys.stdout.flush()
            wrapper.count += 1
            return func(*args, **kwargs)
        wrapper.count = 0
        return wrapper

    logged_func = logging_decorator(func)
    res = g.apply(logged_func, *args, **kwargs)
    sys.stdout.write('\033[D \033[D' * 4 + format(100., '3.0f') + '%' + '\n')
    sys.stdout.flush()
    return res

注意:应用进度百分比updates inline。如果你的函数出错,这就不起作用了。

In [11]: g = df_users.groupby(['userID', 'requestDate'])

In [12]: f = feature_rollup

In [13]: logged_apply(g, f)
apply progress: 100%
Out[13]: 
...

像往常一样,您可以将其作为一种方法添加到groupby对象中:

from pandas.core.groupby import DataFrameGroupBy
DataFrameGroupBy.logged_apply = logged_apply

In [21]: g.logged_apply(f)
apply progress: 100%
Out[21]: 
...

正如评论中提到的,这不是核心熊猫感兴趣实现的功能。但是python允许您为许多pandas对象/方法创建这些对象/方法(这样做将是相当多的工作。。。尽管你应该能够概括这种方法)。

由于流行的需求,tqdm增加了对pandas的支持。与其他答案不同,这个不会明显减慢熊猫的速度--下面是一个DataFrameGroupBy.progress_apply的示例:

import pandas as pd
import numpy as np
from tqdm import tqdm
# from tqdm.auto import tqdm  # for notebooks

df = pd.DataFrame(np.random.randint(0, int(1e8), (10000, 1000)))

# Create and register a new `tqdm` instance with `pandas`
# (can use tqdm_gui, optional kwargs, etc.)
tqdm.pandas()

# Now you can use `progress_apply` instead of `apply`
df.groupby(0).progress_apply(lambda x: x**2)

如果您对它的工作方式感兴趣(以及如何为自己的回调修改它),请参见examples on githubfull documentation on pypi,或者导入模块并运行help(tqdm)

编辑


要直接回答原始问题,请替换:

df_users.groupby(['userID', 'requestDate']).apply(feature_rollup)

使用:

from tqdm import tqdm
tqdm.pandas()
df_users.groupby(['userID', 'requestDate']).progress_apply(feature_rollup)

注意:tqdm<;=v4.8: 对于低于4.8的TQM版本,您必须执行以下操作,而不是tqdm.pandas()

from tqdm import tqdm, tqdm_pandas
tqdm_pandas(tqdm())

相关问题 更多 >