class_docstr: Sample cluster-wide memory usage every <interval> seconds.
  
  **Usage**
  
  .. code-block:: python
  
     client = Client()
     ms = MemorySampler()
  
     with ms.sample("run 1"):
         <run first workflow>
     with ms.sample("run 2"):
         <run second workflow>
     ...
     ms.plot()
  
  or with an asynchronous client:
  
  .. code-block:: python
  
     client = await Client(asynchronous=True)
     ms = MemorySampler()
  
     async with ms.sample("run 1"):
         <run first workflow>
     async with ms.sample("run 2"):
         <run second workflow>
     ...
     ms.plot()
class_docstr_tok: ["Sample","cluster-wide","memory","usage","every","<","interval",">","seconds",".","*","*","Usage","*","*","..","code-block",":",":","python","client","=","Client","(",")","ms","=","MemorySampler","(",")","with","ms.sample","(","``","run","1","''",")",":","<","run","first","workflow",">","with","ms.sample","(","``","run","2","''",")",":","<","run","second","workflow",">","...","ms.plot","(",")","or","with","an","asynchronous","client",":","..","code-block",":",":","python","client","=","await","Client","(","asynchronous=True",")","ms","=","MemorySampler","(",")","async","with","ms.sample","(","``","run","1","''",")",":","<","run","first","workflow",">","async","with","ms.sample","(","``","run","2","''",")",":","<","run","second","workflow",">","...","ms.plot","(",")"]
docstr: Return the data series as a pandas.Dataframe.
  
  Parameters
  ==========
  align : bool, optional
      If True, change the absolute timestamps into time deltas from the first
      sample of each series, so that different series can be visualized side by
      side. If False (the default), use absolute timestamps.
docstr_tok: ["Return","the","data","series","as","a","pandas.Dataframe",".","Parameters","==========","align",":","bool",",","optional","If","True",",","change","the","absolute","timestamps","into","time","deltas","from","the","first","sample","of","each","series",",","so","that","different","series","can","be","visualized","side","by","side",".","If","False","(","the","default",")",",","use","absolute","timestamps","."]
code: def to_pandas(self, *, align: bool = False) -> pd.DataFrame:
      """Return the data series as a pandas.Dataframe.
  
      Parameters
      ==========
      align : bool, optional
          If True, change the absolute timestamps into time deltas from the first
          sample of each series, so that different series can be visualized side by
          side. If False (the default), use absolute timestamps.
      """
      import pandas as pd
  
      ss = {}
      for label, s_list in self.samples.items():
          assert s_list  # There's always at least one sample
          s = pd.DataFrame(s_list).set_index(0)[1]
          s.index = pd.to_datetime(s.index, unit="s")
          s.name = label
          if align:
              # convert datetime to timedelta from the first sample
              s.index -= s.index[0]
          ss[label] = s
  
      df = pd.DataFrame(ss)
  
      if len(ss) > 1:
          # Forward-fill NaNs in the middle of a series created either by overlapping
          # sampling time range or by align=True. Do not ffill series beyond their
          # last sample.
          df = df.ffill().where(~pd.isna(df.bfill()))
  
      return df
  
file_path: distributed/distributed/diagnostics/memory_sampler.py
imports: from __future__ import annotations
  import uuid
  from collections.abc import AsyncIterator, Iterator
  from contextlib import asynccontextmanager, contextmanager
  from datetime import datetime
  from typing import TYPE_CHECKING, Any
  from distributed.compatibility import PeriodicCallback
label_desc: Use image node_id 4 for calling the MemorySampler obj's underlying member method code with example usage: obj.to_pandas() and returns: df