Data structures#
The main data structures are:
Array: can be thought of as a numpyndarraywith a physical unitVector: a container whose components are ArraysDatagroup: a dictionary of Arrays and/or VectorsDataset: a dictionary of Datagroups, and can also contain additional metadata
This notebook aims to give both a description of each structure, and show how they can be used efficiently to manipulate and explore your simulation data. They aim to have an API which is close to the Python dict and the numpy ndarray.
[1]:
import osyris
import numpy as np
We load a data output from a star formation simulation
[2]:
data = osyris.RamsesDataset(8, path="osyrisdata/starformation").load()
Processing 12 files in osyrisdata/starformation/output_00008
16% : read 65623 cells, 0 particles
25% : read 90140 cells, 956 particles
33% : read 118232 cells, 956 particles
41% : read 147100 cells, 956 particles
50% : read 170244 cells, 2109 particles
66% : read 235859 cells, 2109 particles
75% : read 260384 cells, 3065 particles
83% : read 288476 cells, 3065 particles
91% : read 312840 cells, 4217 particles
Loaded: 340488 cells, 4218 particles.
The Dataset class#
The Dataset object that has a __str__ representation, which list all the contents of data in an easy manner:
[3]:
data
[3]:
Dataset: osyrisdata/starformation/output_00008: 71.16 MB
Datagroup: sink 128.00 B
'id' Min: 1.0 Max: 2.0 [] (2,)
'msink' Min: 3.482e+32 Max: 3.485e+32 [g] (2,)
'position' Min: 5.061e+16 Max: 5.192e+16 [cm] (2,), {x,y,z}
'v' Min: 7.464e+04 Max: 7.577e+04 [cm / s] (2,), {x,y,z}
Datagroup: mesh 70.82 MB
'level' Min: 5 Max: 9 [] (340488,)
'cpu' Min: 1 Max: 12 [] (340488,)
'dx' Min: 1.151e+14 Max: 1.842e+15 [cm] (340488,)
'density' Min: 2.376e-19 Max: 8.047e-12 [g / cm ** 3] (340488,)
'thermal_pressure' Min: 8.555e-11 Max: 0.057 [erg / cm ** 3] (340488,)
'internal_energy' Min: 1.283e-10 Max: 0.085 [erg / cm ** 3] (340488,)
'temperature' Min: 10.002 Max: 196.393 [K] (340488,)
'grav_potential' Min: -6.219e+12 Max: 9.126e+10 [cm ** 2 / s ** 2] (340488,)
'position' Min: 1.595e+15 Max: 1.005e+17 [cm] (340488,), {x,y,z}
'velocity' Min: 742.189 Max: 4.216e+05 [cm / s] (340488,), {x,y,z}
'B_left' Min: 2.097e-05 Max: 0.164 [G] (340488,), {x,y,z}
'B_right' Min: 2.097e-05 Max: 0.162 [G] (340488,), {x,y,z}
'grav_acceleration' Min: 4.196e-09 Max: 2.028e-04 [cm / s ** 2] (340488,), {x,y,z}
'B_field' Min: 2.119e-05 Max: 0.157 [G] (340488,), {x,y,z}
'mass' Min: 5.721e-08 Max: 0.006 [M_sun] (340488,)
Datagroup: part 337.44 KB
'mass' Min: 1.651e+29 Max: 1.652e+29 [g] (4218,)
'identity' Min: -2.0 Max: -1.0 [] (4218,)
'levelp' Min: 5.0 Max: 5.0 [] (4218,)
'birth_time' Min: 8.888e-05 Max: 8.892e-05 [] (4218,)
'position' Min: 5.017e+16 Max: 5.237e+16 [cm] (4218,), {x,y,z}
'velocity' Min: 7.464e+04 Max: 7.577e+04 [cm / s] (4218,), {x,y,z}
The Dataset class aims to behave very similarly to a Python dict. To access one element of data, we index it by using the group names
[4]:
data["mesh"]
[4]:
Datagroup: mesh 70.82 MB
'level' Min: 5 Max: 9 [] (340488,)
'cpu' Min: 1 Max: 12 [] (340488,)
'dx' Min: 1.151e+14 Max: 1.842e+15 [cm] (340488,)
'density' Min: 2.376e-19 Max: 8.047e-12 [g / cm ** 3] (340488,)
'thermal_pressure' Min: 8.555e-11 Max: 0.057 [erg / cm ** 3] (340488,)
'internal_energy' Min: 1.283e-10 Max: 0.085 [erg / cm ** 3] (340488,)
'temperature' Min: 10.002 Max: 196.393 [K] (340488,)
'grav_potential' Min: -6.219e+12 Max: 9.126e+10 [cm ** 2 / s ** 2] (340488,)
'position' Min: 1.595e+15 Max: 1.005e+17 [cm] (340488,), {x,y,z}
'velocity' Min: 742.189 Max: 4.216e+05 [cm / s] (340488,), {x,y,z}
'B_left' Min: 2.097e-05 Max: 0.164 [G] (340488,), {x,y,z}
'B_right' Min: 2.097e-05 Max: 0.162 [G] (340488,), {x,y,z}
'grav_acceleration' Min: 4.196e-09 Max: 2.028e-04 [cm / s ** 2] (340488,), {x,y,z}
'B_field' Min: 2.119e-05 Max: 0.157 [G] (340488,), {x,y,z}
'mass' Min: 5.721e-08 Max: 0.006 [M_sun] (340488,)
Each entry in the Dataset is a Datagroup.
It is also possible to store additional metadata under the meta property
[5]:
data.meta
[5]:
{'ncpu': 12,
'ndim': 3,
'levelmin': 5,
'levelmax': 9,
'ngridmax': 100000,
'nstep_coarse': 483,
'boxlen': 0.019140529831525,
'time': <Quantity(1.77991019e+11, 'second')>,
'aexp': 1.0,
'H0': 1.0,
'omega_m': 1.0,
'omega_l': 0.0,
'omega_k': 0.0,
'omega_b': 0.0450000017881393,
'unit_l': 3.08e+18,
'unit_d': 3.8346e-24,
'unit_t': 1977320409468800.0,
'mu_gas': 2.31,
'ngrp': 0,
'nent': 0,
'npscal': 1,
'nextinct': 0,
'ndust': 0,
'ordering type': 'hilbert',
'ir_cloud': 4,
'eos': 0,
'write_cons': 0,
'infofile': 'osyrisdata/starformation/output_00008/info_00008.txt',
'infile': 'osyrisdata/starformation/output_00008',
'nout': 8,
'path': 'osyrisdata/starformation',
'ncells': 340488,
'nparticles': 4218,
'lmax': 9,
'dtold': array([0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4.22046016e-08, 4.22046016e-08, 4.22046016e-08, 4.22046016e-08,
2.10757114e-08]),
'dtnew': array([0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
4.21383676e-08, 4.21383676e-08, 4.21383676e-08, 4.21383676e-08,
2.10626561e-08]),
'gamma': 1.666667}
The Datagroup class#
The Datagroup can be thought of a Python dict of arrays, which enforces shape alignment, so that all members of a Datagroup have the same length.
The elements of a Datagroup can be accessed using the variables names
[6]:
mesh = data["mesh"]
mesh["density"]
[6]:
'density' Min: 2.376e-19 Max: 8.047e-12 [g / cm ** 3] (340488,)
Each entry in the Datagroup is an Array object, which will be described in detail below.
Dataset and Datagroup both provide standard dictionary iterators, which can be used to loop over their contents:
[7]:
data.keys()
[7]:
dict_keys(['sink', 'mesh', 'part'])
[8]:
mesh.keys()
[8]:
dict_keys(['level', 'cpu', 'dx', 'density', 'thermal_pressure', 'internal_energy', 'temperature', 'grav_potential', 'position', 'velocity', 'B_left', 'B_right', 'grav_acceleration', 'B_field', 'mass'])
Because it ensures all its members have the same length, a Datagroup can be sliced along its length
[9]:
mesh[10:20]
[9]:
Datagroup: 2.08 KB
'level' Min: 5 Max: 5 [] (10,)
'cpu' Min: 1 Max: 1 [] (10,)
'dx' Min: 1.842e+15 Max: 1.842e+15 [cm] (10,)
'density' Min: 3.328e-19 Max: 3.034e-18 [g / cm ** 3] (10,)
'thermal_pressure' Min: 1.199e-10 Max: 1.094e-09 [erg / cm ** 3] (10,)
'internal_energy' Min: 1.798e-10 Max: 1.640e-09 [erg / cm ** 3] (10,)
'temperature' Min: 10.002 Max: 10.010 [K] (10,)
'grav_potential' Min: 3.024e+10 Max: 8.658e+10 [cm ** 2 / s ** 2] (10,)
'position' Min: 8.392e+15 Max: 3.258e+16 [cm] (10,), {x,y,z}
'velocity' Min: 3.669e+03 Max: 4.435e+04 [cm / s] (10,), {x,y,z}
'B_left' Min: 2.526e-05 Max: 2.619e-04 [G] (10,), {x,y,z}
'B_right' Min: 2.511e-05 Max: 2.614e-04 [G] (10,), {x,y,z}
'grav_acceleration' Min: 1.935e-08 Max: 5.296e-08 [cm / s ** 2] (10,), {x,y,z}
'B_field' Min: 2.518e-05 Max: 2.617e-04 [G] (10,), {x,y,z}
'mass' Min: 1.046e-06 Max: 9.539e-06 [M_sun] (10,)
The Array class#
Each entry in the Datagroup dictionary is an Array (or Vector, see below) object:
[10]:
a = mesh["density"]
type(a)
[10]:
osyris.core.array.Array
Its string representation lists the array’s name, the minimum and maximum values in the array, its physical unit, and the number of elements in the array.
[11]:
a
[11]:
'density' Min: 2.376e-19 Max: 8.047e-12 [g / cm ** 3] (340488,)
An Array can basically be thought of as a numpy array with a physical unit:
[12]:
a.values
[12]:
array([1.30425047e-18, 1.30410735e-18, 1.30448987e-18, ...,
5.34148563e-16, 1.57773631e-15, 5.55088281e-15])
[13]:
a.unit
[13]:
Operations you would normally perform on a numpy array, such as slicing, are supported:
[14]:
a[101:255]
[14]:
'density' Min: 2.826e-19 Max: 3.587e-18 [g / cm ** 3] (154,)
Note that this returns a view onto the original data, instead of making a copy.
Using numpy’s array_function and array_ufunc protocols, Array also supports most numpy operations, e.g.
[15]:
np.log10(a)
[15]:
'' Min: -18.624 Max: -11.094 [g / cm ** 3] (340488,)
[16]:
np.sum(a)
[16]:
'' Value: 5.339e-10 [g / cm ** 3] ()
Note that in these cases, a new Array is returned, and they are not attached to any Datagroup, and therefore do not have a name. To insert a new Array into a Datagroup, simply use the dictionary syntax
[17]:
mesh["log_rho"] = np.log10(a)
mesh
[17]:
Datagroup: mesh 73.55 MB
'level' Min: 5 Max: 9 [] (340488,)
'cpu' Min: 1 Max: 12 [] (340488,)
'dx' Min: 1.151e+14 Max: 1.842e+15 [cm] (340488,)
'density' Min: 2.376e-19 Max: 8.047e-12 [g / cm ** 3] (340488,)
'thermal_pressure' Min: 8.555e-11 Max: 0.057 [erg / cm ** 3] (340488,)
'internal_energy' Min: 1.283e-10 Max: 0.085 [erg / cm ** 3] (340488,)
'temperature' Min: 10.002 Max: 196.393 [K] (340488,)
'grav_potential' Min: -6.219e+12 Max: 9.126e+10 [cm ** 2 / s ** 2] (340488,)
'position' Min: 1.595e+15 Max: 1.005e+17 [cm] (340488,), {x,y,z}
'velocity' Min: 742.189 Max: 4.216e+05 [cm / s] (340488,), {x,y,z}
'B_left' Min: 2.097e-05 Max: 0.164 [G] (340488,), {x,y,z}
'B_right' Min: 2.097e-05 Max: 0.162 [G] (340488,), {x,y,z}
'grav_acceleration' Min: 4.196e-09 Max: 2.028e-04 [cm / s ** 2] (340488,), {x,y,z}
'B_field' Min: 2.119e-05 Max: 0.157 [G] (340488,), {x,y,z}
'mass' Min: 5.721e-08 Max: 0.006 [M_sun] (340488,)
'log_rho' Min: -18.624 Max: -11.094 [g / cm ** 3] (340488,)
Example: find the system center#
A simple way to find the centre of our protostellar system is to use the coordinate of the cell with the highest density in the simulation.
[18]:
ind = np.argmax(mesh["density"])
center = mesh["position"][ind]
center
[18]:
'position' Value: 2.470e+16, 3.241e+16, 2.942e+16 [cm] (), {x,y,z}
Array arithmetic and units#
Units are automatically handled (and conversions carried out) when performing arithmetic on arrays. For instance, we want to compute a new quantity which represents the mass inside each cell.
The data density is in g / cm**3, while the cell size is in cm, giving
[19]:
mesh["mass"] = mesh["density"] * (mesh["dx"] ** 3)
mesh["mass"]
[19]:
'mass' Min: 1.138e+26 Max: 1.228e+31 [g] (340488,)
This helps to free mental capacity and allows the user to focus on what is important: doing science.
Manual unit conversions#
Sometimes, it is useful to convert from CGS units to other base units:
[20]:
mesh["mass"].to("M_sun")
[20]:
'' Min: 5.721e-08 Max: 0.006 [M_sun] (340488,)
Note that in this case a new Array is returned. If you want to update the entry in your Datagroup, use
[21]:
mesh["mass"] = mesh["mass"].to("M_sun")
Units are properly handled in operations that involve non-base units by first converting both operands to their base units, before performing the operation. In the following example, we compute the mass from a density in g / cm**3 and a cell size in au:
[22]:
dx_in_au = mesh["dx"].to("au")
(mesh["density"] * (dx_in_au**3)).to("M_sun")
[22]:
'' Min: 5.721e-08 Max: 0.006 [M_sun] (340488,)
Units also provide safety#
Physical units also provide a certain level of safety around operations. By assigning some quantities to intermediate variables, it is often easy to lose track of the exact quantity (or at least its dimensionality) that a variable represents.
Physical units can prevent performing operations on mismatching quantities:
[23]:
try:
mesh["density"] + mesh["mass"]
except Exception as e:
print(e)
Cannot convert from 'solar_mass' ([mass]) to 'gram / centimeter ** 3' ([mass] / [length] ** 3)
Physical units can also help find errors in an analysis workflow, when looking at a final value for a computed star formation rate for example, and realising that the final unit represents a quantity per unit volume, while the user was trying to calculate an integrate rate.
Operations with floats#
Operations with floats are also supported:
[24]:
mesh["density"] * 1.0e5
[24]:
'' Min: 2.376e-14 Max: 8.047e-07 [g / cm ** 3] (340488,)
The Vector class#
Datagroups contain scalar variables (such as the gas density above) as well as vector variables. Vector variables have more than one component, represented by a special Vector class, which contains one Array for each component.
A Vector variable can be identified in a Datagroup by the list of components at the end of its string representation {x,y,z}:
[25]:
mesh["velocity"]
[25]:
'velocity' Min: 742.189 Max: 4.216e+05 [cm / s] (340488,), {x,y,z}
The Min and Max values printed above are from the norm of the Vector. The components of the Vector are accessed via the .x, .y, .z properties:
[26]:
mesh["velocity"].y
[26]:
'velocity_y' Min: -3.309e+05 Max: 3.312e+05 [cm / s] (340488,)
The shape of the Vector is the same as the shape of the Array:
[27]:
mesh["velocity"].shape == mesh["density"].shape
[27]:
True
Vector operations#
All operations that can be done on Arrays (including Numpy operations) can also be carried out with Vectors:
[28]:
mesh["velocity"] + mesh["velocity"]
[28]:
'' Min: 1.484e+03 Max: 8.431e+05 [cm / s] (340488,), {x,y,z}
[29]:
np.sum(mesh["velocity"])
[29]:
'' Value: 3.883e+05, -6.226e+04, -2.398e+08 [cm / s] (), {x,y,z}
Vector - Array operations#
In operations that combine both Vectors and Arrays, are automatically broadcasted:
[30]:
mesh["momentum"] = mesh["density"] * mesh["velocity"]
mesh["momentum"]
[30]:
'momentum' Min: 9.680e-16 Max: 1.489e-06 [g / cm ** 2 / s] (340488,), {x,y,z}
Dot and cross prodcuts#
Vectors also provide additionaly functionality, such as dot and cross products
[31]:
mesh["velocity"].dot(mesh["velocity"])
[31]:
'' Min: 5.508e+05 Max: 1.777e+11 [cm ** 2 / s ** 2] (340488,)
[32]:
mesh["position"].cross(mesh["velocity"])
[32]:
'' Min: 1.353e+17 Max: 2.069e+22 [cm ** 2 / s] (340488,), {x,y,z}
Compatibility with Pandas#
It is possible to convert a Datagroup to a Pandas DataFrame, using the to_pandas method.
Note that the physical units are lost in the conversion, so take care when using this!
[33]:
df = mesh.to_pandas()
df
[33]:
| level | cpu | dx | density | thermal_pressure | internal_energy | temperature | grav_potential | position | position_x | ... | B_field | B_field_x | B_field_y | B_field_z | mass | log_rho | momentum | momentum_x | momentum_y | momentum_z | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 5 | 1 | 1.842276e+15 | 1.304250e-18 | 4.698461e-10 | 7.047689e-10 | 10.005541 | 9.125380e+10 | 1.595458e+15 | 9.211380e+14 | ... | 0.000026 | 1.803169e-09 | 2.699627e-09 | 0.000026 | 4.100267e-06 | -17.884639 | 9.709736e-16 | 4.680982e-16 | 6.154301e-16 | 5.872985e-16 |
| 1 | 5 | 1 | 1.842276e+15 | 1.304107e-18 | 4.697946e-10 | 7.046915e-10 | 10.005540 | 7.817903e+10 | 1.571344e+16 | 1.565935e+16 | ... | 0.000026 | 2.036658e-08 | 3.009515e-09 | 0.000026 | 4.099817e-06 | -17.884687 | 5.240005e-15 | 5.136811e-15 | 6.363770e-16 | 8.159919e-16 |
| 2 | 5 | 1 | 1.842276e+15 | 1.304490e-18 | 4.699324e-10 | 7.048983e-10 | 10.005541 | 7.680951e+10 | 1.571344e+16 | 9.211380e+14 | ... | 0.000026 | 2.741827e-09 | 3.510998e-08 | 0.000026 | 4.101020e-06 | -17.884559 | 7.068721e-15 | 5.061374e-16 | 6.989779e-15 | 9.239216e-16 |
| 3 | 5 | 1 | 1.842276e+15 | 7.872865e-19 | 2.835690e-10 | 4.253533e-10 | 10.003957 | 5.894347e+10 | 2.216481e+16 | 1.565935e+16 | ... | 0.000262 | -2.818321e-06 | 6.971902e-06 | 0.000262 | 2.475050e-06 | -18.103867 | 2.930998e-14 | -2.451686e-14 | -1.603411e-14 | -9.518220e-16 |
| 4 | 5 | 1 | 1.842276e+15 | 1.309571e-18 | 4.717633e-10 | 7.076447e-10 | 10.005556 | 5.541099e+10 | 2.216481e+16 | 1.565935e+16 | ... | 0.000025 | 4.727566e-07 | 6.628848e-08 | 0.000025 | 4.116992e-06 | -17.882871 | 1.213410e-14 | 7.888439e-15 | 8.400734e-16 | 9.181673e-15 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 340483 | 9 | 12 | 1.151422e+14 | 2.301678e-16 | 8.431491e-08 | 1.264723e-07 | 10.174326 | -1.593046e+12 | 5.081580e+16 | 3.172169e+16 | ... | 0.000311 | 4.707947e-05 | 5.220070e-05 | 0.000303 | 1.766590e-07 | -15.637955 | 3.784490e-11 | 1.952285e-11 | 3.240493e-11 | 1.007710e-12 |
| 340484 | 9 | 12 | 1.151422e+14 | 1.552000e-16 | 5.662770e-08 | 8.494150e-08 | 10.134048 | -1.263794e+12 | 4.971729e+16 | 3.195197e+16 | ... | 0.000731 | 1.714987e-04 | 5.655733e-04 | 0.000430 | 1.191195e-07 | -15.809108 | 2.451755e-11 | 3.120734e-12 | 2.216341e-11 | 1.000771e-11 |
| 340485 | 9 | 12 | 1.151422e+14 | 5.341486e-16 | 1.981929e-07 | 2.972892e-07 | 10.305568 | -1.366146e+12 | 5.196077e+16 | 3.517596e+16 | ... | 0.010852 | -7.816231e-03 | 4.480761e-04 | 0.007515 | 4.099711e-07 | -15.272338 | 1.156553e-10 | -8.185992e-11 | -8.198295e-12 | 8.128891e-11 |
| 340486 | 9 | 12 | 1.151422e+14 | 1.577736e-15 | 2.365460e-07 | 9.074995e-07 | 10.629056 | -1.281810e+12 | 5.168678e+16 | 3.195197e+16 | ... | 0.002820 | 1.556458e-03 | -1.405341e-03 | 0.001885 | 1.210948e-06 | -14.801966 | 1.903833e-10 | 8.333643e-11 | -1.017183e-10 | 1.376745e-10 |
| 340487 | 9 | 12 | 1.151422e+14 | 5.550883e-15 | 2.432499e-06 | 3.434368e-06 | 11.455150 | -1.308335e+12 | 5.143119e+16 | 3.195197e+16 | ... | 0.006534 | 4.688873e-03 | -1.988809e-03 | 0.004093 | 4.260428e-06 | -14.255638 | 7.344626e-10 | 3.070165e-10 | -1.365416e-10 | 6.530946e-10 |
340488 rows × 38 columns
You can then use some useful features of Pandas, such as groupby, to go further in your data analysis:
[34]:
df.groupby("level").sum()
[34]:
| cpu | dx | density | thermal_pressure | internal_energy | temperature | grav_potential | position | position_x | position_y | ... | B_field | B_field_x | B_field_y | B_field_z | mass | log_rho | momentum | momentum_x | momentum_y | momentum_z | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| level | |||||||||||||||||||||
| 5 | 121814 | 3.772244e+19 | 2.804629e-14 | 0.000010 | 0.000015 | 204873.414421 | 9.782972e+14 | 1.191037e+21 | 6.035591e+20 | 6.035591e+20 | ... | 2.015126 | 3.270362e-12 | -8.594112e-12 | 1.981410 | 0.088171 | -3.671811e+05 | 5.001874e-10 | -4.239929e-18 | 3.825192e-17 | 4.638331e-14 |
| 6 | 501218 | 7.900785e+19 | 2.202408e-13 | 0.000079 | 0.000119 | 858405.225517 | -2.935458e+15 | 4.663338e+21 | 2.528251e+21 | 2.528251e+21 | ... | 16.275584 | 6.007423e-10 | -5.182438e-10 | 14.280334 | 0.086548 | -1.522375e+06 | 7.342950e-09 | 1.963942e-16 | -3.064424e-16 | 6.414165e-13 |
| 7 | 520539 | 4.051625e+19 | 2.190647e-12 | 0.000794 | 0.001191 | 882825.096281 | -2.809380e+16 | 4.574443e+21 | 2.593040e+21 | 2.593040e+21 | ... | 46.979381 | -5.910621e-08 | -9.325901e-10 | 35.667770 | 0.107608 | -1.478413e+06 | 2.011465e-07 | -3.482203e-15 | -8.429184e-14 | -9.994506e-11 |
| 8 | 624831 | 2.159470e+19 | 2.009867e-11 | 0.007478 | 0.011216 | 951430.058160 | -7.652899e+16 | 4.821749e+21 | 2.764121e+21 | 2.764121e+21 | ... | 154.826909 | -2.160208e-05 | -8.758308e-08 | 118.758908 | 0.123409 | -1.490307e+06 | 2.895388e-06 | -2.582842e-12 | -3.919816e-12 | -2.119254e-08 |
| 9 | 392696 | 6.044508e+18 | 5.113368e-10 | 1.062883 | 1.594329 | 576917.878863 | -9.821723e+16 | 2.694000e+21 | 1.547394e+21 | 1.547394e+21 | ... | 634.128194 | 1.764599e-04 | -4.896269e-08 | 341.769392 | 0.392463 | -7.900440e+05 | 1.062042e-04 | 2.907650e-07 | 1.382717e-07 | -6.599697e-07 |
5 rows × 37 columns