@@ -324,6 +324,86 @@ def write(cls, s, file=sys.stdout, end="\n"):
324324 inst .refresh ()
325325 # TODO: make list of all instances incl. absolutely positioned ones?
326326
327+ @classmethod
328+ def pandas (tclass , * targs , ** tkwargs ):
329+ """
330+ Registers the given `tqdm` class with
331+ pandas.core.
332+ ( frame.DataFrame
333+ | series.Series
334+ | groupby.DataFrameGroupBy
335+ | groupby.SeriesGroupBy
336+ ).progress_apply
337+
338+ A new instance will be create every time `progress_apply` is called,
339+ and each instance will automatically close() upon completion.
340+
341+ Parameters
342+ ----------
343+ targs, tkwargs : arguments for the tqdm instance
344+
345+ Examples
346+ --------
347+ >>> import pandas as pd
348+ >>> import numpy as np
349+ >>> from tqdm import tqdm, tqdm_gui
350+ >>>
351+ >>> df = pd.DataFrame(np.random.randint(0, 100, (100000, 6)))
352+ >>> tqdm.pandas(ncols=50) # can use tqdm_gui, optional kwargs, etc
353+ >>> # Now you can use `progress_apply` instead of `apply`
354+ >>> df.groupby(0).progress_apply(lambda x: x**2)
355+
356+ References
357+ ----------
358+ https://stackoverflow.com/questions/18603270/
359+ progress-indicator-during-pandas-operations-python
360+ """
361+ from pandas .core .frame import DataFrame
362+ from pandas .core .series import Series
363+ from pandas .core .groupby import DataFrameGroupBy , SeriesGroupBy
364+
365+ def inner (df , func , * args , ** kwargs ):
366+ """
367+ Parameters
368+ ----------
369+ df : (DataFrame|Series)[GroupBy]
370+ Data (may be grouped).
371+ func : function
372+ To be applied on the (grouped) data.
373+ *args, *kwargs : optional
374+ Transmitted to `df.apply()`.
375+ """
376+ # Precompute total iterations
377+ total = getattr (df , 'ngroups' , None )
378+ if total is None : # not grouped
379+ total = len (df ) if isinstance (df , Series ) \
380+ else df .size // len (df )
381+ else :
382+ total += 1 # pandas calls update once too many
383+
384+ # Init bar
385+ t = tclass (* targs , total = total , ** tkwargs )
386+
387+ # Define bar updating wrapper
388+ def wrapper (* args , ** kwargs ):
389+ t .update ()
390+ return func (* args , ** kwargs )
391+
392+ # Apply the provided function (in *args and **kwargs)
393+ # on the df using our wrapper (which provides bar updating)
394+ result = df .apply (wrapper , * args , ** kwargs )
395+
396+ # Close bar and return pandas calculation result
397+ t .close ()
398+ return result
399+
400+ # Monkeypatch pandas to provide easy methods
401+ # Enable custom tqdm progress in pandas!
402+ DataFrame .progress_apply = inner
403+ DataFrameGroupBy .progress_apply = inner
404+ Series .progress_apply = inner
405+ SeriesGroupBy .progress_apply = inner
406+
327407 def __init__ (self , iterable = None , desc = None , total = None , leave = True ,
328408 file = sys .stderr , ncols = None , mininterval = 0.1 ,
329409 maxinterval = 10.0 , miniters = None , ascii = None , disable = False ,
0 commit comments