{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Visualize Time Series"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import helpers\n",
    "load = helpers.DataBaseLoader(user='mt361', password='tian01054017', schema='mimiciv_derived')"
   ]
  },
  {
   "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>stay_id</th>\n",
       "      <th>charttime</th>\n",
       "      <th>urineoutput</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>30000153</td>\n",
       "      <td>2174-09-29 12:12:00</td>\n",
       "      <td>280.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>30000153</td>\n",
       "      <td>2174-09-29 14:00:00</td>\n",
       "      <td>45.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>30000153</td>\n",
       "      <td>2174-09-29 15:00:00</td>\n",
       "      <td>50.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>30000153</td>\n",
       "      <td>2174-09-29 16:00:00</td>\n",
       "      <td>50.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>30000153</td>\n",
       "      <td>2174-09-29 17:00:00</td>\n",
       "      <td>45.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    stay_id           charttime  urineoutput\n",
       "0  30000153 2174-09-29 12:12:00        280.0\n",
       "1  30000153 2174-09-29 14:00:00         45.0\n",
       "2  30000153 2174-09-29 15:00:00         50.0\n",
       "3  30000153 2174-09-29 16:00:00         50.0\n",
       "4  30000153 2174-09-29 17:00:00         45.0"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "urineoutput_df = load['urine_output']\n",
    "urineoutput_df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "def visualize(df, title: str, value: str, num_patients: int=10):\n",
    "    assert num_patients % 3 == 0\n",
    "    grouped = df.groupby('stay_id')\n",
    "    fig, axes = plt.subplots(nrows=num_patients // 3, ncols=3, figsize=(20, 5 * (num_patients // 3)))\n",
    "    for i, (stay_id, group_data) in enumerate(grouped):\n",
    "        if i == num_patients:\n",
    "            break\n",
    "        sns.lineplot(x=group_data['charttime'], y=group_data[value], marker='s', linewidth=1, ax=axes[i // 3, i % 3])\n",
    "        axes[i // 3, i % 3].set_title(f\"{title} for stay_id {stay_id}\")\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 595996 characters]",
      "text/plain": [
       "<Figure size 2000x3000 with 18 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "visualize(urineoutput_df, 'Urine Output', 'urineoutput', num_patients=18)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "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>subject_id</th>\n",
       "      <th>stay_id</th>\n",
       "      <th>charttime</th>\n",
       "      <th>heart_rate</th>\n",
       "      <th>sbp</th>\n",
       "      <th>dbp</th>\n",
       "      <th>mbp</th>\n",
       "      <th>sbp_ni</th>\n",
       "      <th>dbp_ni</th>\n",
       "      <th>mbp_ni</th>\n",
       "      <th>resp_rate</th>\n",
       "      <th>temperature</th>\n",
       "      <th>temperature_site</th>\n",
       "      <th>spo2</th>\n",
       "      <th>glucose</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>10000032</td>\n",
       "      <td>39553978</td>\n",
       "      <td>2180-07-23 14:00:00</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>37.06</td>\n",
       "      <td>Oral</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>10000032</td>\n",
       "      <td>39553978</td>\n",
       "      <td>2180-07-23 14:11:00</td>\n",
       "      <td>NaN</td>\n",
       "      <td>84.0</td>\n",
       "      <td>48.0</td>\n",
       "      <td>56.0</td>\n",
       "      <td>84.0</td>\n",
       "      <td>48.0</td>\n",
       "      <td>56.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>None</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>10000032</td>\n",
       "      <td>39553978</td>\n",
       "      <td>2180-07-23 14:12:00</td>\n",
       "      <td>91.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>24.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>None</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>10000032</td>\n",
       "      <td>39553978</td>\n",
       "      <td>2180-07-23 14:13:00</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>None</td>\n",
       "      <td>98.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>10000032</td>\n",
       "      <td>39553978</td>\n",
       "      <td>2180-07-23 14:30:00</td>\n",
       "      <td>93.0</td>\n",
       "      <td>95.0</td>\n",
       "      <td>59.0</td>\n",
       "      <td>67.0</td>\n",
       "      <td>95.0</td>\n",
       "      <td>59.0</td>\n",
       "      <td>67.0</td>\n",
       "      <td>21.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>None</td>\n",
       "      <td>97.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   subject_id   stay_id           charttime  heart_rate   sbp   dbp   mbp  \\\n",
       "0    10000032  39553978 2180-07-23 14:00:00         NaN   NaN   NaN   NaN   \n",
       "1    10000032  39553978 2180-07-23 14:11:00         NaN  84.0  48.0  56.0   \n",
       "2    10000032  39553978 2180-07-23 14:12:00        91.0   NaN   NaN   NaN   \n",
       "3    10000032  39553978 2180-07-23 14:13:00         NaN   NaN   NaN   NaN   \n",
       "4    10000032  39553978 2180-07-23 14:30:00        93.0  95.0  59.0  67.0   \n",
       "\n",
       "   sbp_ni  dbp_ni  mbp_ni  resp_rate  temperature temperature_site  spo2  \\\n",
       "0     NaN     NaN     NaN        NaN        37.06             Oral   NaN   \n",
       "1    84.0    48.0    56.0        NaN          NaN             None   NaN   \n",
       "2     NaN     NaN     NaN       24.0          NaN             None   NaN   \n",
       "3     NaN     NaN     NaN        NaN          NaN             None  98.0   \n",
       "4    95.0    59.0    67.0       21.0          NaN             None  97.0   \n",
       "\n",
       "   glucose  \n",
       "0      NaN  \n",
       "1      NaN  \n",
       "2      NaN  \n",
       "3      NaN  \n",
       "4      NaN  "
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vitals_df = load['vitalsign']\n",
    "vitals_df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 684156 characters]",
      "text/plain": [
       "<Figure size 2000x3000 with 18 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "visualize(vitals_df, 'Heart Rate', 'heart_rate', num_patients=18)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "\n",
    "def get_time_diff(vitalsigns, value: str):\n",
    "    vitalsigns = vitalsigns[vitalsigns[value].notnull()]\n",
    "    assert not vitalsigns[value].isnull().any()\n",
    "    vitalsigns['charttime'] = pd.to_numeric(vitalsigns['charttime'])\n",
    "    vitalsigns['time_diff'] = vitalsigns['charttime'].diff() / (3.6 * 1e12)\n",
    "    vitalsigns = vitalsigns[vitalsigns['time_diff'] >= 0]\n",
    "    return vitalsigns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/var/folders/t0/wpl_qfjd5s3cczhlskc092xm0000gp/T/ipykernel_86782/3101594736.py:6: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  vitalsigns['charttime'] = pd.to_numeric(vitalsigns['charttime'])\n",
      "/var/folders/t0/wpl_qfjd5s3cczhlskc092xm0000gp/T/ipykernel_86782/3101594736.py:7: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  vitalsigns['time_diff'] = vitalsigns['charttime'].diff() / (3.6 * 1e12)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "count    6.421682e+06\n",
       "mean     9.701352e+02\n",
       "std      1.851875e+04\n",
       "min      1.666667e-02\n",
       "25%      1.000000e+00\n",
       "50%      1.000000e+00\n",
       "75%      1.000000e+00\n",
       "max      8.526008e+05\n",
       "Name: time_diff, dtype: float64"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "heartrate_df = get_time_diff(vitals_df, 'heart_rate')\n",
    "heartrate_df['time_diff'].describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "16.73405814862835"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "100 * len(heartrate_df[ (heartrate_df['time_diff'] > 1.5) | (heartrate_df['time_diff'] < 0.7) ]) / len(heartrate_df)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "gen",
   "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.11.4"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
