{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Pandas support\n",
    "\n",
    "It is convenient to use the Pandas package when dealing with numerical data, so Pint provides PintArray. A PintArray is a Pandas Extension Array, which allows Pandas to recognise the Quantity and store it in Pandas DataFrames and Series."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Basic example"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This example will show the simplist way to use pandas with pint and the underlying objects. It's slightly fiddly as you are not reading from a file. A more normal use case is given in Reading a csv.\n",
    "\n",
    "First some imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd \n",
    "import pint"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, we create a DataFrame with PintArrays as columns."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>torque</th>\n",
       "      <th>angular_velocity</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  torque angular_velocity\n",
       "0      1                1\n",
       "1      2                2\n",
       "2      2                2\n",
       "3      3                3"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.DataFrame({\n",
    "    \"torque\": pd.Series([1, 2, 2, 3], dtype=\"pint[lbf ft]\"),\n",
    "    \"angular_velocity\": pd.Series([1, 2, 2, 3], dtype=\"pint[rpm]\"),\n",
    "})\n",
    "df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Operations with columns are units aware so behave as we would intuitively expect."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>torque</th>\n",
       "      <th>angular_velocity</th>\n",
       "      <th>power</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>9</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  torque angular_velocity power\n",
       "0      1                1     1\n",
       "1      2                2     4\n",
       "2      2                2     4\n",
       "3      3                3     9"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df['power'] = df['torque'] * df['angular_velocity']\n",
    "df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can see the columns' units in the dtypes attribute"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torque                                       pint[foot * force_pound]\n",
       "angular_velocity                         pint[revolutions_per_minute]\n",
       "power               pint[foot * force_pound * revolutions_per_minute]\n",
       "dtype: object"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.dtypes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Each column can be accessed as a Pandas Series"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    1\n",
       "1    4\n",
       "2    4\n",
       "3    9\n",
       "Name: power, dtype: pint[foot * force_pound * revolutions_per_minute]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.power"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Which contains a PintArray"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PintArray([1 foot * force_pound * revolutions_per_minute,\n",
       "           4 foot * force_pound * revolutions_per_minute,\n",
       "           4 foot * force_pound * revolutions_per_minute,\n",
       "           9 foot * force_pound * revolutions_per_minute],\n",
       "          dtype='pint[foot * force_pound * revolutions_per_minute]')"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.power.values"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The PintArray contains a Quantity"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\\[\\begin{pmatrix}1 & 4 & 4 & 9\\end{pmatrix} foot force_pound revolutions_per_minute\\]"
      ],
      "text/latex": [
       "$\\begin{pmatrix}1 & 4 & 4 & 9\\end{pmatrix}\\ \\mathrm{foot} \\cdot \\mathrm{force_pound} \\cdot \\mathrm{revolutions_per_minute}$"
      ],
      "text/plain": [
       "array([1, 4, 4, 9]) <Unit('foot * force_pound * revolutions_per_minute')>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.power.values.quantity"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pandas Series accessors are provided for most Quantity properties and methods, which will convert the result to a Series where possible."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "foot force_pound revolutions_per_minute"
      ],
      "text/latex": [
       "$\\mathrm{foot} \\cdot \\mathrm{force_pound} \\cdot \\mathrm{revolutions_per_minute}$"
      ],
      "text/plain": [
       "<Unit('foot * force_pound * revolutions_per_minute')>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.power.pint.units"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PintArray([0.00014198092353610376 kilowatt, 0.000567923694144415 kilowatt,\n",
       "           0.000567923694144415 kilowatt, 0.0012778283118249339 kilowatt],\n",
       "          dtype='pint[kilowatt]')"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.power.pint.to(\"kW\").values"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Reading from csv\n",
    "\n",
    "Reading from files is the far more standard way to use pandas. To facilitate this, DataFrame accessors are provided to make it easy to get to PintArrays. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd \n",
    "import pint\n",
    "import io"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here's the contents of the csv file."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_data = '''speed,mech power,torque,rail pressure,fuel flow rate,fluid power\n",
    "rpm,kW,N m,bar,l/min,kW\n",
    "1000.0,,10.0,1000.0,10.0,\n",
    "1100.0,,10.0,100000000.0,10.0,\n",
    "1200.0,,10.0,1000.0,10.0,\n",
    "1200.0,,10.0,1000.0,10.0,'''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's read that into a DataFrame.\n",
    "Here io.StringIO is used in place of reading a file from disk, whereas a csv file path would typically be used and is shown commented."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>speed</th>\n",
       "      <th>mech power</th>\n",
       "      <th>torque</th>\n",
       "      <th>rail pressure</th>\n",
       "      <th>fuel flow rate</th>\n",
       "      <th>fluid power</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>rpm</th>\n",
       "      <th>kW</th>\n",
       "      <th>N m</th>\n",
       "      <th>bar</th>\n",
       "      <th>l/min</th>\n",
       "      <th>kW</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1000.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1100.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>10.0</td>\n",
       "      <td>100000000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1200.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1200.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    speed mech power torque rail pressure fuel flow rate fluid power\n",
       "      rpm         kW    N m           bar          l/min          kW\n",
       "0  1000.0        NaN   10.0        1000.0           10.0         NaN\n",
       "1  1100.0        NaN   10.0   100000000.0           10.0         NaN\n",
       "2  1200.0        NaN   10.0        1000.0           10.0         NaN\n",
       "3  1200.0        NaN   10.0        1000.0           10.0         NaN"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.read_csv(io.StringIO(test_data),header=[0,1])\n",
    "# df = pd.read_csv(\"/path/to/test_data.csv\",header=[0,1])\n",
    "df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then use the DataFrame's pint accessor's quantify method to convert the columns from `np.ndarray`s to PintArrays, with units from the bottom column level."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "speed           rpm      float64\n",
       "mech power      kW       float64\n",
       "torque          N m      float64\n",
       "rail pressure   bar      float64\n",
       "fuel flow rate  l/min    float64\n",
       "fluid power     kW       float64\n",
       "dtype: object"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.dtypes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>speed</th>\n",
       "      <th>mech power</th>\n",
       "      <th>torque</th>\n",
       "      <th>rail pressure</th>\n",
       "      <th>fuel flow rate</th>\n",
       "      <th>fluid power</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1000.0</td>\n",
       "      <td>nan</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>nan</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1100.0</td>\n",
       "      <td>nan</td>\n",
       "      <td>10.0</td>\n",
       "      <td>100000000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>nan</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1200.0</td>\n",
       "      <td>nan</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>nan</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1200.0</td>\n",
       "      <td>nan</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>nan</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    speed mech power torque rail pressure fuel flow rate fluid power\n",
       "0  1000.0        nan   10.0        1000.0           10.0         nan\n",
       "1  1100.0        nan   10.0   100000000.0           10.0         nan\n",
       "2  1200.0        nan   10.0        1000.0           10.0         nan\n",
       "3  1200.0        nan   10.0        1000.0           10.0         nan"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_ = df.pint.quantify(level=-1)\n",
    "df_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As previously, operations between DataFrame columns are unit aware"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    10000.0\n",
       "1    11000.0\n",
       "2    12000.0\n",
       "3    12000.0\n",
       "dtype: pint[meter * newton * revolutions_per_minute]"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_.speed*df_.torque"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>speed</th>\n",
       "      <th>mech power</th>\n",
       "      <th>torque</th>\n",
       "      <th>rail pressure</th>\n",
       "      <th>fuel flow rate</th>\n",
       "      <th>fluid power</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1000.0</td>\n",
       "      <td>nan</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>nan</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1100.0</td>\n",
       "      <td>nan</td>\n",
       "      <td>10.0</td>\n",
       "      <td>100000000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>nan</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1200.0</td>\n",
       "      <td>nan</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>nan</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1200.0</td>\n",
       "      <td>nan</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>nan</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    speed mech power torque rail pressure fuel flow rate fluid power\n",
       "0  1000.0        nan   10.0        1000.0           10.0         nan\n",
       "1  1100.0        nan   10.0   100000000.0           10.0         nan\n",
       "2  1200.0        nan   10.0        1000.0           10.0         nan\n",
       "3  1200.0        nan   10.0        1000.0           10.0         nan"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>speed</th>\n",
       "      <th>mech power</th>\n",
       "      <th>torque</th>\n",
       "      <th>rail pressure</th>\n",
       "      <th>fuel flow rate</th>\n",
       "      <th>fluid power</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1000.0</td>\n",
       "      <td>10000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>10000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1100.0</td>\n",
       "      <td>11000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>100000000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000000000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1200.0</td>\n",
       "      <td>12000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>10000.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1200.0</td>\n",
       "      <td>12000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>10000.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    speed mech power torque rail pressure fuel flow rate   fluid power\n",
       "0  1000.0    10000.0   10.0        1000.0           10.0       10000.0\n",
       "1  1100.0    11000.0   10.0   100000000.0           10.0  1000000000.0\n",
       "2  1200.0    12000.0   10.0        1000.0           10.0       10000.0\n",
       "3  1200.0    12000.0   10.0        1000.0           10.0       10000.0"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_['mech power'] = df_.speed*df_.torque\n",
    "df_['fluid power'] = df_['fuel flow rate'] * df_['rail pressure']\n",
    "df_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The DataFrame's `pint.dequantify` method then allows us to retrieve the units information as a header row once again."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>speed</th>\n",
       "      <th>mech power</th>\n",
       "      <th>torque</th>\n",
       "      <th>rail pressure</th>\n",
       "      <th>fuel flow rate</th>\n",
       "      <th>fluid power</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>unit</th>\n",
       "      <th>revolutions_per_minute</th>\n",
       "      <th>meter * newton * revolutions_per_minute</th>\n",
       "      <th>meter * newton</th>\n",
       "      <th>bar</th>\n",
       "      <th>liter / minute</th>\n",
       "      <th>bar * liter / minute</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1000.0</td>\n",
       "      <td>10000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1.000000e+04</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1100.0</td>\n",
       "      <td>11000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>100000000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1.000000e+09</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1200.0</td>\n",
       "      <td>12000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1.000000e+04</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1200.0</td>\n",
       "      <td>12000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1.000000e+04</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                      speed                              mech power  \\\n",
       "unit revolutions_per_minute meter * newton * revolutions_per_minute   \n",
       "0                    1000.0                                 10000.0   \n",
       "1                    1100.0                                 11000.0   \n",
       "2                    1200.0                                 12000.0   \n",
       "3                    1200.0                                 12000.0   \n",
       "\n",
       "             torque rail pressure fuel flow rate          fluid power  \n",
       "unit meter * newton           bar liter / minute bar * liter / minute  \n",
       "0              10.0        1000.0           10.0         1.000000e+04  \n",
       "1              10.0   100000000.0           10.0         1.000000e+09  \n",
       "2              10.0        1000.0           10.0         1.000000e+04  \n",
       "3              10.0        1000.0           10.0         1.000000e+04  "
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_.pint.dequantify()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This allows for some rather powerful abilities. For example, to change single column units"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>speed</th>\n",
       "      <th>mech power</th>\n",
       "      <th>torque</th>\n",
       "      <th>rail pressure</th>\n",
       "      <th>fuel flow rate</th>\n",
       "      <th>fluid power</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>unit</th>\n",
       "      <th>revolutions_per_minute</th>\n",
       "      <th>kilowatt</th>\n",
       "      <th>meter * newton</th>\n",
       "      <th>bar</th>\n",
       "      <th>liter / minute</th>\n",
       "      <th>kilowatt</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1000.0</td>\n",
       "      <td>1.047198</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1.666667e+01</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1100.0</td>\n",
       "      <td>1.151917</td>\n",
       "      <td>10.0</td>\n",
       "      <td>100000000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1.666667e+06</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1200.0</td>\n",
       "      <td>1.256637</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1.666667e+01</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1200.0</td>\n",
       "      <td>1.256637</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1.666667e+01</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                      speed mech power         torque rail pressure  \\\n",
       "unit revolutions_per_minute   kilowatt meter * newton           bar   \n",
       "0                    1000.0   1.047198           10.0        1000.0   \n",
       "1                    1100.0   1.151917           10.0   100000000.0   \n",
       "2                    1200.0   1.256637           10.0        1000.0   \n",
       "3                    1200.0   1.256637           10.0        1000.0   \n",
       "\n",
       "     fuel flow rate   fluid power  \n",
       "unit liter / minute      kilowatt  \n",
       "0              10.0  1.666667e+01  \n",
       "1              10.0  1.666667e+06  \n",
       "2              10.0  1.666667e+01  \n",
       "3              10.0  1.666667e+01  "
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_['fluid power'] = df_['fluid power'].pint.to(\"kW\")\n",
    "df_['mech power'] = df_['mech power'].pint.to(\"kW\")\n",
    "df_.pint.dequantify()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The units are harder to read than they need be, so lets change pints default format for displaying units."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>speed</th>\n",
       "      <th>mech power</th>\n",
       "      <th>torque</th>\n",
       "      <th>rail pressure</th>\n",
       "      <th>fuel flow rate</th>\n",
       "      <th>fluid power</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>unit</th>\n",
       "      <th>rpm</th>\n",
       "      <th>kW</th>\n",
       "      <th>N·m</th>\n",
       "      <th>bar</th>\n",
       "      <th>l/min</th>\n",
       "      <th>kW</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1000.0</td>\n",
       "      <td>1.047198</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1.666667e+01</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1100.0</td>\n",
       "      <td>1.151917</td>\n",
       "      <td>10.0</td>\n",
       "      <td>100000000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1.666667e+06</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1200.0</td>\n",
       "      <td>1.256637</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1.666667e+01</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1200.0</td>\n",
       "      <td>1.256637</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1.666667e+01</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       speed mech power torque rail pressure fuel flow rate   fluid power\n",
       "unit     rpm         kW    N·m           bar          l/min            kW\n",
       "0     1000.0   1.047198   10.0        1000.0           10.0  1.666667e+01\n",
       "1     1100.0   1.151917   10.0   100000000.0           10.0  1.666667e+06\n",
       "2     1200.0   1.256637   10.0        1000.0           10.0  1.666667e+01\n",
       "3     1200.0   1.256637   10.0        1000.0           10.0  1.666667e+01"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pint.PintType.ureg.default_format = \"~P\"\n",
    "df_.pint.dequantify()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "or the entire table's units"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>speed</th>\n",
       "      <th>mech power</th>\n",
       "      <th>torque</th>\n",
       "      <th>rail pressure</th>\n",
       "      <th>fuel flow rate</th>\n",
       "      <th>fluid power</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>unit</th>\n",
       "      <th>rad/s</th>\n",
       "      <th>kg·m²/s³</th>\n",
       "      <th>kg·m²/s²</th>\n",
       "      <th>kg/m/s²</th>\n",
       "      <th>m³/s</th>\n",
       "      <th>kg·m²/s³</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>104.719755</td>\n",
       "      <td>1047.197551</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1.000000e+08</td>\n",
       "      <td>0.000167</td>\n",
       "      <td>1.666667e+04</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>115.191731</td>\n",
       "      <td>1151.917306</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1.000000e+13</td>\n",
       "      <td>0.000167</td>\n",
       "      <td>1.666667e+09</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>125.663706</td>\n",
       "      <td>1256.637061</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1.000000e+08</td>\n",
       "      <td>0.000167</td>\n",
       "      <td>1.666667e+04</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>125.663706</td>\n",
       "      <td>1256.637061</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1.000000e+08</td>\n",
       "      <td>0.000167</td>\n",
       "      <td>1.666667e+04</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           speed   mech power   torque rail pressure fuel flow rate  \\\n",
       "unit       rad/s     kg·m²/s³ kg·m²/s²       kg/m/s²           m³/s   \n",
       "0     104.719755  1047.197551     10.0  1.000000e+08       0.000167   \n",
       "1     115.191731  1151.917306     10.0  1.000000e+13       0.000167   \n",
       "2     125.663706  1256.637061     10.0  1.000000e+08       0.000167   \n",
       "3     125.663706  1256.637061     10.0  1.000000e+08       0.000167   \n",
       "\n",
       "       fluid power  \n",
       "unit      kg·m²/s³  \n",
       "0     1.666667e+04  \n",
       "1     1.666667e+09  \n",
       "2     1.666667e+04  \n",
       "3     1.666667e+04  "
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_.pint.to_base_units().pint.dequantify()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Advanced example\n",
    "This example shows alternative ways to use pint with pandas and other features.\n",
    "\n",
    "Start with the same imports."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd \n",
    "import pint"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We'll be use a shorthand for PintArray"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "PA_ = pint.PintArray"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And set up a unit registry and quantity shorthand."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "ureg=pint.UnitRegistry()\n",
    "Q_=ureg.Quantity"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Operations between PintArrays of different unit registry will not work. We can change the unit registry that will be used in creating new PintArrays to prevent this issue."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "pint.PintType.ureg = ureg"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "These are the possible ways to create a PintArray.\n",
    "\n",
    "Note that pint[unit] must be used for the Series constuctor, whereas the PintArray constructor allows the unit string or object."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>length</th>\n",
       "      <th>width</th>\n",
       "      <th>distance</th>\n",
       "      <th>height</th>\n",
       "      <th>depth</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  length width distance height depth\n",
       "0      1     2        2      2     2\n",
       "1      2     3        3      3     3"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.DataFrame({\n",
    "        \"length\" : pd.Series([1,2], dtype=\"pint[m]\"),\n",
    "        \"width\" : PA_([2,3], dtype=\"pint[m]\"),\n",
    "        \"distance\" : PA_([2,3], dtype=\"m\"),\n",
    "        \"height\" : PA_([2,3], dtype=ureg.m),\n",
    "        \"depth\" : PA_.from_1darray_quantity(Q_([2,3],ureg.m)),\n",
    "    })\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "meter"
      ],
      "text/latex": [
       "$\\mathrm{meter}$"
      ],
      "text/plain": [
       "<Unit('meter')>"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.length.values.units"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "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.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
