DataFrame.py 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. """
  2. This file is part of the openPMD-api.
  3. Copyright 2021 openPMD contributors
  4. Authors: Axel Huebl
  5. License: LGPLv3+
  6. """
  7. import math
  8. import numpy as np
  9. try:
  10. import pandas as pd
  11. found_pandas = True
  12. except ImportError:
  13. found_pandas = False
  14. def particles_to_dataframe(particle_species, slice=None):
  15. """
  16. Load all records of a particle species into a Pandas DataFrame.
  17. Parameters
  18. ----------
  19. particle_species : openpmd_api.ParticleSpecies
  20. A ParticleSpecies class in openPMD-api.
  21. slice : np.s_, optional
  22. A numpy slice that can be used to load only a sub-selection of
  23. particles.
  24. Returns
  25. -------
  26. pandas.DataFrame
  27. A pandas dataframe with particles as index and openPMD record
  28. components of the particle_species as columns.
  29. Raises
  30. ------
  31. ImportError
  32. Raises an exception if pandas is not installed
  33. See Also
  34. --------
  35. numpy.s_ : the slice object to sub-select
  36. openpmd_api.BaseRecordComponent.available_chunks : available chunks that
  37. are optimal arguments for the slice parameter
  38. pandas.DataFrame : the central dataframe object created here
  39. """
  40. if not found_pandas:
  41. raise ImportError("pandas NOT found. Install pandas for DataFrame "
  42. "support.")
  43. if slice is None:
  44. slice = np.s_[()]
  45. columns = {}
  46. for record_name, record in particle_species.items():
  47. for rc_name, rc in record.items():
  48. if record.scalar:
  49. column_name = record_name
  50. else:
  51. column_name = record_name + "_" + rc_name
  52. columns[column_name] = rc[slice]
  53. particle_species.series_flush()
  54. if not math.isclose(1.0, rc.unit_SI):
  55. columns[column_name] = np.multiply(
  56. columns[column_name], rc.unit_SI)
  57. return pd.DataFrame(columns)