{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Working With Sessions\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Import the LArray library:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbsphinx": "hidden" }, "outputs": [], "source": [ "%xmode Minimal" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from larray import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Three Kinds Of Sessions " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "They are three ways to group objects in LArray:\n", "\n", " * [Session](../api.rst#session): is an ordered dict-like container with special I/O methods. Although the *autocomplete*\\* feature on the objects stored in the session is available in the larray-editor, it is not available in development tools like PyCharm making it cumbersome to use.\n", " * [CheckedSession](../api.rst#checkedsession): provides the same methods as Session objects but are defined in a completely different way (see example below). The *autocomplete*\\* feature is both available in the larray-editor and in development tools (PyCharm). In addition, the type of each stored object is protected. Optionally, it is possible to constrain the axes and dtype of arrays using ``CheckedArray``.\n", " * [CheckedParameters](../api.rst#checkedparameters): is a special version of CheckedSession in which the value of all stored objects (parameters) is frozen after initialization.\n", " \n", " \\* *Autocomplete* is the feature in which development tools try to predict the variable or function a user intends to enter after only a few characters have been typed (like word completion in cell phones)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Creating Sessions " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Session\n", "\n", "Create a session:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# define some scalars, axes and arrays\n", "variant = 'baseline'\n", "\n", "country = Axis('country=Belgium,France,Germany')\n", "gender = Axis('gender=Male,Female')\n", "time = Axis('time=2013..2017')\n", "\n", "population = zeros([country, gender, time])\n", "births = zeros([country, gender, time])\n", "deaths = zeros([country, gender, time])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# create an empty session and objects one by one after\n", "s = Session()\n", "s.variant = variant\n", "s.country = country\n", "s.gender = gender\n", "s.time = time\n", "s.population = population\n", "s.births = births\n", "s.deaths = deaths\n", "\n", "print(s.summary())" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# or create a session in one step by passing all objects to the constructor\n", "s = Session(variant=variant, country=country, gender=gender, time=time, \n", " population=population, births=births, deaths=deaths)\n", "\n", "print(s.summary())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### CheckedSession\n", "\n", "The syntax to define a checked-session is a bit specific:\n", "\n", "```python\n", "class MySession(CheckedSession):\n", " # Variables can be declared in two ways:\n", " # a) by specifying only the type of the variable (to be initialized later)\n", " var1: Type\n", " # b) by giving an initialization value.\n", " # In that case, the type is deduced from the initialization value\n", " var2 = initialization value\n", " # Additionally, axes and dtype of Array variables can be constrained \n", " # using the special type CheckedArray\n", " arr1: CheckedArray([list, of, axes], dtype) = initialization value\n", "```\n", "\n", "Check the example below:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class Demography(CheckedSession):\n", " # (convention is to declare parameters (read-only objects) in capital letters)\n", " # Declare 'VARIANT' parameter as of type string.\n", " # 'VARIANT' will be initialized when a 'Demography' session will be created\n", " VARIANT: str\n", " # declare variables with an initialization value.\n", " # Their type is deduced from their initialization value. \n", " COUNTRY = Axis('country=Belgium,France,Germany')\n", " GENDER = Axis('gender=Male,Female')\n", " TIME = Axis('time=2013..2017')\n", " population = zeros([COUNTRY, GENDER, TIME], dtype=int)\n", " births = zeros([COUNTRY, GENDER, TIME], dtype=int)\n", " # declare 'deaths' with constrained axes and dtype.\n", " # Its type (Array), axes and dtype are not modifiable.\n", " # It will be initialized with 0\n", " deaths: CheckedArray([COUNTRY, GENDER, TIME], int) = 0\n", "\n", "d = Demography(VARIANT='baseline')\n", "\n", "print(d.summary())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Loading and Dumping Sessions\n", "\n", "One of the main advantages of grouping arrays, axes and groups in session objects is that you can load and save all of them in one shot. Like arrays, it is possible to associate metadata to a session. These can be saved and loaded in all file formats. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Loading Sessions (CSV, Excel, HDF5)\n", "\n", "To load the items of a session, you have two options:\n", "\n", "1) Instantiate a new session and pass the path to the Excel/HDF5 file or to the directory containing CSV files to the Session constructor:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# create a new Session object and load all arrays, axes, groups and metadata \n", "# from all CSV files located in the passed directory\n", "csv_dir = get_example_filepath('demography_eurostat')\n", "s = Session(csv_dir)\n", "\n", "# create a new Session object and load all arrays, axes, groups and metadata\n", "# stored in the passed Excel file\n", "filepath_excel = get_example_filepath('demography_eurostat.xlsx')\n", "s = Session(filepath_excel)\n", "\n", "# create a new Session object and load all arrays, axes, groups and metadata\n", "# stored in the passed HDF5 file\n", "filepath_hdf = get_example_filepath('demography_eurostat.h5')\n", "s = Session(filepath_hdf)\n", "\n", "print(s.summary())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "2) Call the ``load`` method on an existing session and pass the path to the Excel/HDF5 file or to the directory containing CSV files as first argument:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# create a session containing 3 axes, 2 groups and one array 'population'\n", "filepath = get_example_filepath('population_only.xlsx')\n", "s = Session(filepath)\n", "\n", "print(s.summary())" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# call the load method on the previous session and add the 'births' and 'deaths' arrays to it\n", "filepath = get_example_filepath('births_and_deaths.xlsx')\n", "s.load(filepath)\n", "\n", "print(s.summary())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The ``load`` method offers some options:\n", "\n", "1) Using the ``names`` argument, you can specify which items to load:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "births_and_deaths_session = Session()\n", "\n", "# use the names argument to only load births and deaths arrays\n", "births_and_deaths_session.load(filepath_hdf, names=['births', 'deaths'])\n", "\n", "print(births_and_deaths_session.summary())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "2) Setting the ``display`` argument to True, the ``load`` method will print a message each time a new item is loaded: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s = Session()\n", "\n", "# with display=True, the load method will print a message\n", "# each time a new item is loaded\n", "s.load(filepath_hdf, display=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Dumping Sessions (CSV, Excel, HDF5)\n", "\n", "To save a session, you need to call the ``save`` method. The first argument is the path to a Excel/HDF5 file or to a directory if items are saved to CSV files:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# save items of a session in CSV files.\n", "# Here, the save method will create a 'demography' directory in which CSV files will be written \n", "s.save('demography')\n", "\n", "# save the session to an HDF5 file\n", "s.save('demography.h5')\n", "\n", "# save the session to an Excel file\n", "s.save('demography.xlsx')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " Note: Concerning the CSV and Excel formats, the metadata is saved in one Excel sheet (CSV file) named `__metadata__(.csv)`. This sheet (CSV file) name cannot be changed. \n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The ``save`` method has several arguments:\n", "\n", "1) Using the ``names`` argument, you can specify which items to save:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# use the names argument to only save births and deaths arrays\n", "s.save('demography.h5', names=['births', 'deaths'])\n", "\n", "# load session saved in 'demography.h5' to see its content\n", "Session('demography.h5').names" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "2) By default, dumping a session to an Excel or HDF5 file will overwrite it. By setting the ``overwrite`` argument to False, you can choose to update the existing Excel or HDF5 file: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "population = read_csv('./demography/population.csv')\n", "pop_ses = Session([('population', population)])\n", "\n", "# by setting overwrite to False, the destination file is updated instead of overwritten.\n", "# The items already stored in the file but not present in the session are left intact. \n", "# On the contrary, the items that exist in both the file and the session are completely overwritten.\n", "pop_ses.save('demography.h5', overwrite=False)\n", "\n", "# load session saved in 'demography.h5' to see its content\n", "Session('demography.h5').names" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "3) Setting the ``display`` argument to True, the ``save`` method will print a message each time an item is dumped: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# with display=True, the save method will print a message\n", "# each time an item is dumped\n", "s.save('demography.h5', display=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exploring Content\n", "\n", "To get the list of items names of a session, use the [names](../_generated/larray.Session.names.rst#larray.Session.names) shortcut (be careful that the list is sorted alphabetically and does not follow the internal order!):" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# load a session representing the results of a demographic model\n", "filepath_hdf = get_example_filepath('demography_eurostat.h5')\n", "s = Session(filepath_hdf)\n", "\n", "# print the content of the session\n", "print(s.names)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To get more information of items of a session, the [summary](../_generated/larray.Session.summary.rst#larray.Session.summary) will provide not only the names of items but also the list of labels in the case of axes or groups and the list of axes, the shape and the dtype in the case of arrays:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# print the content of the session\n", "print(s.summary())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Selecting And Filtering Items\n", "\n", "Session objects work like ordinary ``dict`` Python objects. To select an item, use the usual syntax ``['']``: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s['population']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A simpler way consists in the use the syntax ``.``:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s.population" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " **Warning:** The syntax ``session_var.item_name`` will work as long as you don't use any special character like ``, ; :`` in the item's name.\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To return a new session with selected items, use the syntax ``[list, of, item, names]``:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s_selected = s['population', 'births', 'deaths']\n", "\n", "s_selected.names" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " **Warning:** The same selection as above can be applied on a checked-session **but the returned object is a normal session and NOT a checked-session**. This means that you will loose all the benefits (autocomplete, protection on type, axes and dtype) of checked-sessions. \n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "d_selected = d['births', 'deaths']\n", "\n", "# test if v_selected is a checked-session\n", "print('is still a check-session?', isinstance(d_selected, CheckedSession))\n", "#test if v_selected is a normal session\n", "print('is now a normal session?', isinstance(d_selected, Session))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The [filter](../_generated/larray.Session.filter.rst#larray.Session.filter) method allows you to select all items of the same kind (i.e. all axes, or groups or arrays) or all items with names satisfying a given pattern:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# select only arrays of a session\n", "s.filter(kind=Array)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# selection all items with a name starting with a letter between a and k\n", "s.filter(pattern='[a-k]*')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " **Warning:** Using the *filter()* method on a checked-session **will return a normal session and NOT a checked-session**. This means that you will loose all the benefits (autocomplete, protection on type, axes and dtype) of checked-sessions. \n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "d_filtered = d.filter(pattern='[a-k]*')\n", "\n", "# test if v_selected is a checked-session\n", "print('is still a check-session?', isinstance(d_filtered, CheckedSession))\n", "#test if v_selected is a normal session\n", "print('is now a normal session?', isinstance(d_filtered, Session))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Iterating over Items\n", "\n", "Like the built-in Python ``dict`` objects, Session objects provide methods to iterate over items: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# iterate over item names\n", "for key in s.keys():\n", " print(key)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# iterate over items\n", "for value in s.values():\n", " if isinstance(value, Array):\n", " print(value.info)\n", " else:\n", " print(repr(value))\n", " print()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# iterate over names and items\n", "for key, value in s.items():\n", " if isinstance(value, Array):\n", " print(key, ':')\n", " print(value.info)\n", " else:\n", " print(key, ':', repr(value))\n", " print()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Manipulating Checked Sessions\n", "\n", "**Note**: this section only concerns objects declared in checked-sessions.\n", "\n", "Let's create a simplified version of the *Demography* checked-session we have defined above:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class Demography(CheckedSession):\n", " COUNTRY = Axis('country=Belgium,France,Germany')\n", " GENDER = Axis('gender=Male,Female')\n", " TIME = Axis('time=2013..2017')\n", " population = zeros([COUNTRY, GENDER, TIME], dtype=int)\n", " # declare the deaths array with constrained axes and dtype\n", " deaths: CheckedArray([COUNTRY, GENDER, TIME], int) = 0\n", "\n", "d = Demography()\n", "\n", "print(d.summary())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One of the specificities of checked-sessions is that the type of the contained objects is protected (it cannot change). Any attempt to assign a value of different type will raise an error:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# The population variable was initialized with the zeros() function which returns an Array object.\n", "# The declared type of the population variable is Array and is protected \n", "d.population = Axis('population=child,teenager,adult,elderly')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The *death* array has been declared as a [CheckedArray](../api.rst#checkedarray). \n", "As a consequence, its axes are protected. \n", "Trying to assign a value with incompatible axes raises an error:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "AGE = Axis('age=0..100')\n", "d.deaths = zeros([d.COUNTRY, AGE, d.GENDER, d.TIME])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The *deaths* array is also constrained by its declared dtype *int*. This means that if you try to assign a value of type *float* instead of *int*, the value will be converted to *int* if possible: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "d.deaths = 1.2\n", "d.deaths" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or raise an error: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "d.deaths = 'undead'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is possible to add a new variable after the checked-session has been initialized but in that case, a warning message is printed (in case you misspelled the name of variable while trying to modify it):" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# misspell population (forgot the 'a')\n", "d.popultion = 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Arithmetic Operations On Sessions\n", "\n", "Session objects accept binary operations with a scalar:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# get population, births and deaths in millions\n", "s_div = s / 1e6\n", "\n", "s_div.population" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "with an array (please read the documentation of the [random.choice](../_generated/larray.random.choice.rst#larray.random.choice) function first if you don't know it):" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from larray import random\n", "random_increment = random.choice([-1, 0, 1], p=[0.3, 0.4, 0.3], axes=s.population.axes) * 1000\n", "random_increment" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# add some variables of a session by a common array\n", "s_rand = s['population', 'births', 'deaths'] + random_increment\n", "\n", "s_rand.population" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "with another session:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# compute the difference between each array of the two sessions\n", "s_diff = s - s_rand\n", "\n", "s_diff.births" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Applying Functions On All Arrays\n", "\n", "In addition to the classical arithmetic operations, the [apply](../_generated/larray.Session.apply.rst#larray.Session.apply) method can be used to apply the same function on all arrays. This function should take a single element argument and return a single value:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# add the next year to all arrays\n", "def add_next_year(array):\n", " if 'time' in array.axes.names:\n", " last_year = array.time.i[-1] \n", " return array.append('time', 0, last_year + 1)\n", " else:\n", " return array\n", "\n", "s_with_next_year = s.apply(add_next_year)\n", "\n", "print('population array before calling apply:')\n", "print(s.population)\n", "print()\n", "print('population array after calling apply:')\n", "print(s_with_next_year.population)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is possible to pass a function with additional arguments:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# add the next year to all arrays.\n", "# Use the 'copy_values_from_last_year flag' to indicate \n", "# whether to copy values from the last year\n", "def add_next_year(array, copy_values_from_last_year):\n", " if 'time' in array.axes.names:\n", " last_year = array.time.i[-1]\n", " value = array[last_year] if copy_values_from_last_year else 0\n", " return array.append('time', value, last_year + 1)\n", " else:\n", " return array\n", "\n", "s_with_next_year = s.apply(add_next_year, True)\n", "\n", "print('population array before calling apply:')\n", "print(s.population)\n", "print()\n", "print('population array after calling apply:')\n", "print(s_with_next_year.population)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is also possible to apply a function on non-Array objects of a session. Please refer the documentation of the [apply](../_generated/larray.Session.apply.rst#larray.Session.apply) method." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Comparing Sessions\n", "\n", "Being able to compare two sessions may be useful when you want to compare two different models expected to give the same results or when you have updated your model and want to see what are the consequences of the recent changes." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Session objects](../api.rst#session) provide the two methods to compare two sessions: [equals](../_generated/larray.Session.equals.rst#larray.Session.equals) and [element_equals](../_generated/larray.Session.element_equals.rst#larray.Session.element_equals):\n", "\n", "- The ``equals`` method will return True if **all items** from both sessions are identical, False otherwise.\n", "- The ``element_equals`` method will compare items of two sessions one by one and return an array of boolean values." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# load a session representing the results of a demographic model\n", "filepath_hdf = get_example_filepath('demography_eurostat.h5')\n", "s = Session(filepath_hdf)\n", "\n", "# create a copy of the original session\n", "s_copy = s.copy()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 'element_equals' compare arrays one by one\n", "s.element_equals(s_copy)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 'equals' returns True if all items of the two sessions have exactly the same items\n", "s.equals(s_copy)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# slightly modify the 'population' array for some labels combination\n", "s_copy.population += random_increment " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# the 'population' array is different between the two sessions\n", "s.element_equals(s_copy)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 'equals' returns False if at least one item of the two sessions are different in values or axes\n", "s.equals(s_copy)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# reset the 'copy' session as a copy of the original session\n", "s_copy = s.copy()\n", "\n", "# add an array to the 'copy' session\n", "s_copy.gender_ratio = s_copy.population.ratio('gender')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# the 'gender_ratio' array is not present in the original session\n", "s.element_equals(s_copy)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 'equals' returns False if at least one item is not present in the two sessions\n", "s.equals(s_copy)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The ``==`` operator return a new session with boolean arrays with elements compared element-wise: \n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# reset the 'copy' session as a copy of the original session\n", "s_copy = s.copy()\n", "\n", "# slightly modify the 'population' array for some labels combination\n", "s_copy.population += random_increment" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s_check_same_values = s == s_copy\n", "\n", "s_check_same_values.population" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This also works for axes and groups:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s_check_same_values.time" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The ``!=`` operator does the opposite of ``==`` operator: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s_check_different_values = s != s_copy\n", "\n", "s_check_different_values.population" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A more visual way is to use the [compare](../_generated/larray.compare.rst#larray.compare) function which will open the ``Editor``.\n", "\n", "```python\n", "compare(s, s_alternative, names=['baseline', 'lower_birth_rate'])\n", "```\n", "\n", "![compare two sessions](../_static/compare_tutorial.png)" ] } ], "metadata": { "celltoolbar": "Edit Metadata", "kernelspec": { "display_name": "Python 3", "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.10" }, "livereveal": { "autolaunch": false, "scroll": true } }, "nbformat": 4, "nbformat_minor": 2 }