{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Tutorial part 2\n", "\n", "Here we'll continue learning about the ``PfLine`` class. \n", "\n", "In [part 1](part1.ipynb) we saw 'flat' portfolio lines, i.e., portfolio lines without nested children. These portfolio lines have a single value for each timestamp for each dimension (i.e., for a price-and-volume portfolio line: one price value, one power value, one energy value, one revenue value).\n", "\n", "We'll look at nested portfolio lines in this part of the tutorial. \n", "\n", "## Example data\n", "\n", "Let's first use the mock functions to get some timeseries and (flat) portfolio lines:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import portfolyo as pf\n", "import pandas as pd\n", "\n", "index = pd.date_range(\"2024\", freq=\"D\", periods=366)\n", "# Creating some distinct timeseries (the details here are not important).\n", "ts_offtake_B2C = -1 * pf.dev.w_offtake(index, avg=100, year_amp=0.3, week_amp=0.25)\n", "ts_offtake_B2B = -1 * pf.dev.w_offtake(index, avg=50, year_amp=0.1, week_amp=0.05)\n", "# turning these timeseries into portfolio lines.\n", "offtake_B2C = pf.PfLine({\"w\": ts_offtake_B2C})\n", "offtake_B2B = pf.PfLine({\"w\": ts_offtake_B2B})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We already saw that we can do arithmatic with portfolio lines, and by adding them together we can get the total offtake portfolio line:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PfLine object with volume information.\n", ". Start: 2024-01-01 00:00:00 (incl) . Timezone : none \n", ". End : 2025-01-01 00:00:00 (excl) . Start-of-day: 00:00:00 \n", ". Freq : (366 datapoints)\n", " w q\n", " MW MWh\n", "\n", "2024-01-01 00:00:00 -174.8 -4 196\n", "2024-01-02 00:00:00 -196.4 -4 714\n", "2024-01-03 00:00:00 -192.4 -4 619\n", "2024-01-04 00:00:00 -195.6 -4 696\n", "2024-01-05 00:00:00 -196.0 -4 703\n", "2024-01-06 00:00:00 -176.2 -4 229\n", "2024-01-07 00:00:00 -141.5 -3 396\n", "2024-01-08 00:00:00 -174.6 -4 191\n", "2024-01-09 00:00:00 -194.9 -4 678\n", "2024-01-10 00:00:00 -193.6 -4 647\n", ".. .. ..\n", "2024-12-23 00:00:00 -172.0 -4 128\n", "2024-12-24 00:00:00 -193.8 -4 650\n", "2024-12-25 00:00:00 -193.9 -4 654\n", "2024-12-26 00:00:00 -192.7 -4 626\n", "2024-12-27 00:00:00 -194.5 -4 667\n", "2024-12-28 00:00:00 -176.0 -4 224\n", "2024-12-29 00:00:00 -142.1 -3 410\n", "2024-12-30 00:00:00 -172.3 -4 135\n", "2024-12-31 00:00:00 -196.1 -4 707" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "offtake_B2C + offtake_B2B" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is again a flat, childless portfolio line; the contributions of the individual portfolios are lost. Often, this is exactly what we want.\n", "\n", "## Portfolio line with children\n", "\n", "In some circumstances, however, we might want to retain the individual data. This is possible: we can combine these two flat volume-only portfolio lines into a new volume-only portfolio line, by specifying in a dictionary that uses their names as keys. Like so:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PfLine object with volume information.\n", ". Start: 2024-01-01 00:00:00 (incl) . Timezone : none \n", ". End : 2025-01-01 00:00:00 (excl) . Start-of-day: 00:00:00 \n", ". Freq : (366 datapoints)\n", ". Children: 'B2C' (volume), 'B2B' (volume)\n", " w q\n", " MW MWh\n", "\n", "2024-01-01 00:00:00 -174.8 -4 196\n", "2024-01-02 00:00:00 -196.4 -4 714\n", "2024-01-03 00:00:00 -192.4 -4 619\n", "2024-01-04 00:00:00 -195.6 -4 696\n", "2024-01-05 00:00:00 -196.0 -4 703\n", "2024-01-06 00:00:00 -176.2 -4 229\n", "2024-01-07 00:00:00 -141.5 -3 396\n", "2024-01-08 00:00:00 -174.6 -4 191\n", "2024-01-09 00:00:00 -194.9 -4 678\n", "2024-01-10 00:00:00 -193.6 -4 647\n", ".. .. ..\n", "2024-12-23 00:00:00 -172.0 -4 128\n", "2024-12-24 00:00:00 -193.8 -4 650\n", "2024-12-25 00:00:00 -193.9 -4 654\n", "2024-12-26 00:00:00 -192.7 -4 626\n", "2024-12-27 00:00:00 -194.5 -4 667\n", "2024-12-28 00:00:00 -176.0 -4 224\n", "2024-12-29 00:00:00 -142.1 -3 410\n", "2024-12-30 00:00:00 -172.3 -4 135\n", "2024-12-31 00:00:00 -196.1 -4 707" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "offtake = pf.PfLine({\"B2C\": offtake_B2C, \"B2B\": offtake_B2B})\n", "offtake" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Superficially, this is the exact same object as the one before it. And unless we specify that we are interested in one of the children, we are working with the exact same aggregate data.\n", "\n", "### Accessing the children\n", "\n", "However, as can be seen in the header, this portfolio line has children, which have the names we specified for them: ``\"B2C\"`` and ``\"B2B\"``. If we want, we can access these by using their names as an index, e.g.:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PfLine object with volume information.\n", ". Start: 2024-01-01 00:00:00 (incl) . Timezone : none \n", ". End : 2025-01-01 00:00:00 (excl) . Start-of-day: 00:00:00 \n", ". Freq : (366 datapoints)\n", " w q\n", " MW MWh\n", "\n", "2024-01-01 00:00:00 -125.2 -3 005\n", "2024-01-02 00:00:00 -145.0 -3 479\n", "2024-01-03 00:00:00 -141.3 -3 391\n", "2024-01-04 00:00:00 -143.6 -3 447\n", "2024-01-05 00:00:00 -144.3 -3 464\n", "2024-01-06 00:00:00 -125.6 -3 014\n", "2024-01-07 00:00:00 -93.8 -2 251\n", "2024-01-08 00:00:00 -123.9 -2 974\n", "2024-01-09 00:00:00 -143.6 -3 447\n", "2024-01-10 00:00:00 -141.7 -3 401\n", ".. .. ..\n", "2024-12-23 00:00:00 -121.5 -2 916\n", "2024-12-24 00:00:00 -142.5 -3 421\n", "2024-12-25 00:00:00 -141.5 -3 395\n", "2024-12-26 00:00:00 -142.0 -3 409\n", "2024-12-27 00:00:00 -142.2 -3 412\n", "2024-12-28 00:00:00 -125.4 -3 009\n", "2024-12-29 00:00:00 -95.7 -2 296\n", "2024-12-30 00:00:00 -122.8 -2 947\n", "2024-12-31 00:00:00 -143.4 -3 442" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "offtake[\"B2C\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Nesting like this is not limited to one level.\n", "\n", "## Arithmatic with children\n", "\n", "All of the arithmatic operations that we can do with flat portfolio lines, we can also do with portfolio lines that have children.\n", "\n", "In some operations, the children can be retained (i.e., are present in the resulting portfolio line). In some, however, they cannot, and the portfolio line is flattened. In that case, a ``PfLineFlattenedWarning`` is issued:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "c:\\users\\ruud.wijtvliet\\ruud\\python\\dev\\portfolyo\\portfolyo\\core\\pfline\\enable_arithmatic.py:82: PfLineFlattenedWarning: When adding a FlatPfLine and NestedPfLine, the NestedPfLine is flattened.\n", " warnings.warn(\n" ] } ], "source": [ "new_offtake = offtake - pf.Q_(10.0, \"MWh\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "See [the section on arithmatic](../core/pfline.rst#operations-arithmatic) for more details on when a portfolio line's children are retained and when not." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This tutorial is continued [in part 3](part3.ipynb)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3.8.13 ('pf38')", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.13" }, "orig_nbformat": 4, "vscode": { "interpreter": { "hash": "642a4be8010ca5d45039b988c1d8379a91572488c4d23a0b88e966c6713c7e45" } } }, "nbformat": 4, "nbformat_minor": 2 }