
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "auto_examples/10_calculated_attributes.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_auto_examples_10_calculated_attributes.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_auto_examples_10_calculated_attributes.py:


Calculated Attributes
=====================

Schema-backed calculated attributes keep derived values close to the block
model schema. This example derives ``tonnes`` from ``density * volume`` and
then derives ``contained_metal`` from ``tonnes * grade``.

The ``volume`` is available as a column from the block model geometry.

.. GENERATED FROM PYTHON SOURCE LINES 11-20

.. code-block:: Python


    import tempfile
    from pathlib import Path

    import pandas as pd

    from parq_blockmodel import ParquetBlockModel
    from parq_blockmodel.utils.demo_block_model import create_demo_blockmodel








.. GENERATED FROM PYTHON SOURCE LINES 21-22

Create a small block model with base attributes.

.. GENERATED FROM PYTHON SOURCE LINES 22-37

.. code-block:: Python


    temp_dir = Path(tempfile.gettempdir()) / "calculated_attributes_example"
    temp_dir.mkdir(parents=True, exist_ok=True)

    df = create_demo_blockmodel(
        shape=(2, 2, 2),
        block_size=(10.0, 10.0, 5.0),
        corner=(0.0, 0.0, 0.0),
        index_type="world_centroids",
    )
    df["density"] = 2.4 + 0.05 * df["depth"]
    df["grade"] = 0.1 + 0.01 * df["depth"]

    df[["density", "grade"]].head()






.. raw:: html

    <div class="output_subarea output_html rendered_html output_result">
    <div>
    <style scoped>
        .dataframe tbody tr th:only-of-type {
            vertical-align: middle;
        }

        .dataframe tbody tr th {
            vertical-align: top;
        }

        .dataframe thead th {
            text-align: right;
        }
    </style>
    <table border="1" class="dataframe">
      <thead>
        <tr style="text-align: right;">
          <th></th>
          <th></th>
          <th></th>
          <th>density</th>
          <th>grade</th>
        </tr>
        <tr>
          <th>x</th>
          <th>y</th>
          <th>z</th>
          <th></th>
          <th></th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th rowspan="4" valign="top">5.0</th>
          <th rowspan="2" valign="top">5.0</th>
          <th>2.5</th>
          <td>2.775</td>
          <td>0.175</td>
        </tr>
        <tr>
          <th>7.5</th>
          <td>2.525</td>
          <td>0.125</td>
        </tr>
        <tr>
          <th rowspan="2" valign="top">15.0</th>
          <th>2.5</th>
          <td>2.775</td>
          <td>0.175</td>
        </tr>
        <tr>
          <th>7.5</th>
          <td>2.525</td>
          <td>0.125</td>
        </tr>
        <tr>
          <th>15.0</th>
          <th>5.0</th>
          <th>2.5</th>
          <td>2.775</td>
          <td>0.175</td>
        </tr>
      </tbody>
    </table>
    </div>
    </div>
    <br />
    <br />

.. GENERATED FROM PYTHON SOURCE LINES 38-46

.. code-block:: Python

    try:
        import df_eval  # noqa: F401
        from pandera import Column, DataFrameSchema
    except ImportError:
        print(
            "Install parq-blockmodel[schema] to run the schema-backed part of this example."
        )








.. GENERATED FROM PYTHON SOURCE LINES 47-50

Build the schema-backed model when the optional schema dependencies are
installed. The schema stores the calculated-column expressions in Pandera
metadata under ``df-eval``.

.. GENERATED FROM PYTHON SOURCE LINES 50-80

.. code-block:: Python


    schema = DataFrameSchema(
        columns={
            "density": Column(float, coerce=True, nullable=True),
            "grade": Column(float, coerce=True, nullable=True),
            "tonnes": Column(
                float,
                coerce=True,
                nullable=True,
                required=False,
                metadata={"df-eval": {"expr": "density * volume"}},
            ),
            "contained_metal": Column(
                float,
                coerce=True,
                nullable=True,
                required=False,
                metadata={"df-eval": {"expr": "tonnes * grade"}},
            ),
        },
        strict=False,
    )

    pbm = ParquetBlockModel.from_dataframe(
        df[["density", "grade"]],
        filename=temp_dir / "calculated_attributes.parquet",
        schema=schema,
        overwrite=True,
    )








.. GENERATED FROM PYTHON SOURCE LINES 81-82

We can read only the calculated columns...

.. GENERATED FROM PYTHON SOURCE LINES 82-86

.. code-block:: Python


    calculated: pd.DataFrame = pbm.read(columns=["tonnes", "contained_metal"], index="ijk", dense=True)
    calculated.head()






.. raw:: html

    <div class="output_subarea output_html rendered_html output_result">
    <div>
    <style scoped>
        .dataframe tbody tr th:only-of-type {
            vertical-align: middle;
        }

        .dataframe tbody tr th {
            vertical-align: top;
        }

        .dataframe thead th {
            text-align: right;
        }
    </style>
    <table border="1" class="dataframe">
      <thead>
        <tr style="text-align: right;">
          <th></th>
          <th></th>
          <th></th>
          <th>tonnes</th>
          <th>contained_metal</th>
        </tr>
        <tr>
          <th>i</th>
          <th>j</th>
          <th>k</th>
          <th></th>
          <th></th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th rowspan="4" valign="top">0</th>
          <th rowspan="2" valign="top">0</th>
          <th>0</th>
          <td>1387.5</td>
          <td>242.8125</td>
        </tr>
        <tr>
          <th>1</th>
          <td>1262.5</td>
          <td>157.8125</td>
        </tr>
        <tr>
          <th rowspan="2" valign="top">1</th>
          <th>0</th>
          <td>1387.5</td>
          <td>242.8125</td>
        </tr>
        <tr>
          <th>1</th>
          <td>1262.5</td>
          <td>157.8125</td>
        </tr>
        <tr>
          <th>1</th>
          <th>0</th>
          <th>0</th>
          <td>1387.5</td>
          <td>242.8125</td>
        </tr>
      </tbody>
    </table>
    </div>
    </div>
    <br />
    <br />

.. GENERATED FROM PYTHON SOURCE LINES 87-88

Or we can read all columns, including the calculated attributes

.. GENERATED FROM PYTHON SOURCE LINES 88-91

.. code-block:: Python


    calculated: pd.DataFrame = pbm.read(index="ijk", dense=True, include_calculated=True)
    calculated.head()





.. raw:: html

    <div class="output_subarea output_html rendered_html output_result">
    <div>
    <style scoped>
        .dataframe tbody tr th:only-of-type {
            vertical-align: middle;
        }

        .dataframe tbody tr th {
            vertical-align: top;
        }

        .dataframe thead th {
            text-align: right;
        }
    </style>
    <table border="1" class="dataframe">
      <thead>
        <tr style="text-align: right;">
          <th></th>
          <th></th>
          <th></th>
          <th>density</th>
          <th>grade</th>
          <th>tonnes</th>
          <th>contained_metal</th>
          <th>block_id</th>
          <th>world_id</th>
          <th>i</th>
          <th>j</th>
          <th>k</th>
          <th>x</th>
          <th>y</th>
          <th>z</th>
          <th>volume</th>
        </tr>
        <tr>
          <th>i</th>
          <th>j</th>
          <th>k</th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th rowspan="4" valign="top">0</th>
          <th rowspan="2" valign="top">0</th>
          <th>0</th>
          <td>2.775</td>
          <td>0.175</td>
          <td>1387.5</td>
          <td>242.8125</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>5.0</td>
          <td>5.0</td>
          <td>2.5</td>
          <td>500.0</td>
        </tr>
        <tr>
          <th>1</th>
          <td>2.525</td>
          <td>0.125</td>
          <td>1262.5</td>
          <td>157.8125</td>
          <td>1</td>
          <td>147488</td>
          <td>0</td>
          <td>0</td>
          <td>1</td>
          <td>5.0</td>
          <td>5.0</td>
          <td>7.5</td>
          <td>500.0</td>
        </tr>
        <tr>
          <th rowspan="2" valign="top">1</th>
          <th>0</th>
          <td>2.775</td>
          <td>0.175</td>
          <td>1387.5</td>
          <td>242.8125</td>
          <td>2</td>
          <td>589952</td>
          <td>0</td>
          <td>1</td>
          <td>0</td>
          <td>5.0</td>
          <td>15.0</td>
          <td>2.5</td>
          <td>500.0</td>
        </tr>
        <tr>
          <th>1</th>
          <td>2.525</td>
          <td>0.125</td>
          <td>1262.5</td>
          <td>157.8125</td>
          <td>3</td>
          <td>737440</td>
          <td>0</td>
          <td>1</td>
          <td>1</td>
          <td>5.0</td>
          <td>15.0</td>
          <td>7.5</td>
          <td>500.0</td>
        </tr>
        <tr>
          <th>1</th>
          <th>0</th>
          <th>0</th>
          <td>2.775</td>
          <td>0.175</td>
          <td>1387.5</td>
          <td>242.8125</td>
          <td>4</td>
          <td>294976</td>
          <td>1</td>
          <td>0</td>
          <td>0</td>
          <td>15.0</td>
          <td>5.0</td>
          <td>2.5</td>
          <td>500.0</td>
        </tr>
      </tbody>
    </table>
    </div>
    </div>
    <br />
    <br />


.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (0 minutes 0.054 seconds)


.. _sphx_glr_download_auto_examples_10_calculated_attributes.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: 10_calculated_attributes.ipynb <10_calculated_attributes.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: 10_calculated_attributes.py <10_calculated_attributes.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: 10_calculated_attributes.zip <10_calculated_attributes.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
