{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h1>14. Introduction to Pandas</h1>\n",
    "<h2>11/01/2023</h2>\n",
    "\n",
    "<h2>14.0 Last Time...</h2>\n",
    "<ul>\n",
    "    <li>The <b>operator</b> package enables us to use a function called <b>attrgetter()</b> to grab attribute information from various classes.</li>\n",
    "    <li>The <b>sorted()</b> function lets us sort data alphabetically or numerically as needed.</li>\n",
    "    <li>NumPy's <b>meshgrid()</b> module lets us create a grid from lat/lon vectors.</li> \n",
    "</ul>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2>14.1 Why Pandas?</h2>\n",
    "\n",
    "Python's standard library has some tools for working with CSV files, but Pandas makes life a whole lot easier! It handles missing data well and also allows for quick calculations and plotting (which we'll be talking about in a couple weeks). A Pandas <b>dataframe</b> is a lot like an Excel spreadsheet, but it's a lot faster and more flexible."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Here's the new library we'll want for today:\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's begin by using a tool we're familiar with that should work pretty well for this kind of data: dictionaries!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[23, 45, 12]\n"
     ]
    }
   ],
   "source": [
    "data = {\"name\":[\"john\",\"bob\",\"dan\"], \"age\":[23,45,12],\"salary\":[23333,43555,90000],\"title\":[\"CFO\",\"VP\",\"CTO\"]}\n",
    "print(data[\"age\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "So far so good, but if we want to get the designation for the employee Sam, that can get a little complex. Pandas will make this endeavor easier and more intuitive.\n",
    "\n",
    "Pandas features two data structures:\n",
    "<ul>\n",
    "    <li><b>Series:</b> 1-D labeled arrays that resemble dictionaries</li>\n",
    "    <li><b>DataFrame:</b> (most common) 2-D like a spreadsheet</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   name  age  salary title\n",
      "0  john   23   23333   CFO\n",
      "1   bob   45   43555    VP\n",
      "2   dan   12   90000   CTO\n"
     ]
    }
   ],
   "source": [
    "employees = pd.DataFrame(data)\n",
    "print(employees)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Remember from our object-oriented programming lectures: a DataFrame is just an object! We can list its attributes and methods using dir()."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['T',\n",
       " '_AXIS_LEN',\n",
       " '_AXIS_ORDERS',\n",
       " '_AXIS_TO_AXIS_NUMBER',\n",
       " '_HANDLED_TYPES',\n",
       " '__abs__',\n",
       " '__add__',\n",
       " '__and__',\n",
       " '__annotations__',\n",
       " '__array__',\n",
       " '__array_priority__',\n",
       " '__array_ufunc__',\n",
       " '__bool__',\n",
       " '__class__',\n",
       " '__contains__',\n",
       " '__copy__',\n",
       " '__dataframe__',\n",
       " '__dataframe_consortium_standard__',\n",
       " '__deepcopy__',\n",
       " '__delattr__',\n",
       " '__delitem__',\n",
       " '__dict__',\n",
       " '__dir__',\n",
       " '__divmod__',\n",
       " '__doc__',\n",
       " '__eq__',\n",
       " '__finalize__',\n",
       " '__floordiv__',\n",
       " '__format__',\n",
       " '__ge__',\n",
       " '__getattr__',\n",
       " '__getattribute__',\n",
       " '__getitem__',\n",
       " '__getstate__',\n",
       " '__gt__',\n",
       " '__hash__',\n",
       " '__iadd__',\n",
       " '__iand__',\n",
       " '__ifloordiv__',\n",
       " '__imod__',\n",
       " '__imul__',\n",
       " '__init__',\n",
       " '__init_subclass__',\n",
       " '__invert__',\n",
       " '__ior__',\n",
       " '__ipow__',\n",
       " '__isub__',\n",
       " '__iter__',\n",
       " '__itruediv__',\n",
       " '__ixor__',\n",
       " '__le__',\n",
       " '__len__',\n",
       " '__lt__',\n",
       " '__matmul__',\n",
       " '__mod__',\n",
       " '__module__',\n",
       " '__mul__',\n",
       " '__ne__',\n",
       " '__neg__',\n",
       " '__new__',\n",
       " '__nonzero__',\n",
       " '__or__',\n",
       " '__pandas_priority__',\n",
       " '__pos__',\n",
       " '__pow__',\n",
       " '__radd__',\n",
       " '__rand__',\n",
       " '__rdivmod__',\n",
       " '__reduce__',\n",
       " '__reduce_ex__',\n",
       " '__repr__',\n",
       " '__rfloordiv__',\n",
       " '__rmatmul__',\n",
       " '__rmod__',\n",
       " '__rmul__',\n",
       " '__ror__',\n",
       " '__round__',\n",
       " '__rpow__',\n",
       " '__rsub__',\n",
       " '__rtruediv__',\n",
       " '__rxor__',\n",
       " '__setattr__',\n",
       " '__setitem__',\n",
       " '__setstate__',\n",
       " '__sizeof__',\n",
       " '__str__',\n",
       " '__sub__',\n",
       " '__subclasshook__',\n",
       " '__truediv__',\n",
       " '__weakref__',\n",
       " '__xor__',\n",
       " '_accessors',\n",
       " '_accum_func',\n",
       " '_agg_examples_doc',\n",
       " '_agg_see_also_doc',\n",
       " '_align_for_op',\n",
       " '_align_frame',\n",
       " '_align_series',\n",
       " '_append',\n",
       " '_arith_method',\n",
       " '_arith_method_with_reindex',\n",
       " '_as_manager',\n",
       " '_attrs',\n",
       " '_box_col_values',\n",
       " '_can_fast_transpose',\n",
       " '_check_inplace_and_allows_duplicate_labels',\n",
       " '_check_is_chained_assignment_possible',\n",
       " '_check_label_or_level_ambiguity',\n",
       " '_check_setitem_copy',\n",
       " '_clear_item_cache',\n",
       " '_clip_with_one_bound',\n",
       " '_clip_with_scalar',\n",
       " '_cmp_method',\n",
       " '_combine_frame',\n",
       " '_consolidate',\n",
       " '_consolidate_inplace',\n",
       " '_construct_axes_dict',\n",
       " '_construct_result',\n",
       " '_constructor',\n",
       " '_constructor_from_mgr',\n",
       " '_constructor_sliced',\n",
       " '_constructor_sliced_from_mgr',\n",
       " '_create_data_for_split_and_tight_to_dict',\n",
       " '_data',\n",
       " '_deprecate_downcast',\n",
       " '_dir_additions',\n",
       " '_dir_deletions',\n",
       " '_dispatch_frame_op',\n",
       " '_drop_axis',\n",
       " '_drop_labels_or_levels',\n",
       " '_ensure_valid_index',\n",
       " '_find_valid_index',\n",
       " '_flags',\n",
       " '_flex_arith_method',\n",
       " '_flex_cmp_method',\n",
       " '_from_arrays',\n",
       " '_from_mgr',\n",
       " '_get_agg_axis',\n",
       " '_get_axis',\n",
       " '_get_axis_name',\n",
       " '_get_axis_number',\n",
       " '_get_axis_resolvers',\n",
       " '_get_block_manager_axis',\n",
       " '_get_bool_data',\n",
       " '_get_cleaned_column_resolvers',\n",
       " '_get_column_array',\n",
       " '_get_index_resolvers',\n",
       " '_get_item_cache',\n",
       " '_get_label_or_level_values',\n",
       " '_get_numeric_data',\n",
       " '_get_value',\n",
       " '_getitem_bool_array',\n",
       " '_getitem_multilevel',\n",
       " '_getitem_nocopy',\n",
       " '_getitem_slice',\n",
       " '_gotitem',\n",
       " '_hidden_attrs',\n",
       " '_indexed_same',\n",
       " '_info_axis',\n",
       " '_info_axis_name',\n",
       " '_info_axis_number',\n",
       " '_info_repr',\n",
       " '_init_mgr',\n",
       " '_inplace_method',\n",
       " '_internal_names',\n",
       " '_internal_names_set',\n",
       " '_is_copy',\n",
       " '_is_homogeneous_type',\n",
       " '_is_label_or_level_reference',\n",
       " '_is_label_reference',\n",
       " '_is_level_reference',\n",
       " '_is_mixed_type',\n",
       " '_is_view',\n",
       " '_iset_item',\n",
       " '_iset_item_mgr',\n",
       " '_iset_not_inplace',\n",
       " '_item_cache',\n",
       " '_iter_column_arrays',\n",
       " '_ixs',\n",
       " '_logical_func',\n",
       " '_logical_method',\n",
       " '_maybe_align_series_as_frame',\n",
       " '_maybe_cache_changed',\n",
       " '_maybe_update_cacher',\n",
       " '_metadata',\n",
       " '_mgr',\n",
       " '_min_count_stat_function',\n",
       " '_needs_reindex_multi',\n",
       " '_pad_or_backfill',\n",
       " '_protect_consolidate',\n",
       " '_reduce',\n",
       " '_reduce_axis1',\n",
       " '_reindex_axes',\n",
       " '_reindex_multi',\n",
       " '_reindex_with_indexers',\n",
       " '_rename',\n",
       " '_replace_columnwise',\n",
       " '_repr_data_resource_',\n",
       " '_repr_fits_horizontal_',\n",
       " '_repr_fits_vertical_',\n",
       " '_repr_html_',\n",
       " '_repr_latex_',\n",
       " '_reset_cache',\n",
       " '_reset_cacher',\n",
       " '_sanitize_column',\n",
       " '_series',\n",
       " '_set_axis',\n",
       " '_set_axis_name',\n",
       " '_set_axis_nocheck',\n",
       " '_set_is_copy',\n",
       " '_set_item',\n",
       " '_set_item_frame_value',\n",
       " '_set_item_mgr',\n",
       " '_set_value',\n",
       " '_setitem_array',\n",
       " '_setitem_frame',\n",
       " '_setitem_slice',\n",
       " '_shift_with_freq',\n",
       " '_should_reindex_frame_op',\n",
       " '_slice',\n",
       " '_sliced_from_mgr',\n",
       " '_stat_function',\n",
       " '_stat_function_ddof',\n",
       " '_take_with_is_copy',\n",
       " '_to_dict_of_blocks',\n",
       " '_to_latex_via_styler',\n",
       " '_typ',\n",
       " '_update_inplace',\n",
       " '_validate_dtype',\n",
       " '_values',\n",
       " '_where',\n",
       " 'abs',\n",
       " 'add',\n",
       " 'add_prefix',\n",
       " 'add_suffix',\n",
       " 'age',\n",
       " 'agg',\n",
       " 'aggregate',\n",
       " 'align',\n",
       " 'all',\n",
       " 'any',\n",
       " 'apply',\n",
       " 'applymap',\n",
       " 'asfreq',\n",
       " 'asof',\n",
       " 'assign',\n",
       " 'astype',\n",
       " 'at',\n",
       " 'at_time',\n",
       " 'attrs',\n",
       " 'axes',\n",
       " 'backfill',\n",
       " 'between_time',\n",
       " 'bfill',\n",
       " 'bool',\n",
       " 'boxplot',\n",
       " 'clip',\n",
       " 'columns',\n",
       " 'combine',\n",
       " 'combine_first',\n",
       " 'compare',\n",
       " 'convert_dtypes',\n",
       " 'copy',\n",
       " 'corr',\n",
       " 'corrwith',\n",
       " 'count',\n",
       " 'cov',\n",
       " 'cummax',\n",
       " 'cummin',\n",
       " 'cumprod',\n",
       " 'cumsum',\n",
       " 'describe',\n",
       " 'diff',\n",
       " 'div',\n",
       " 'divide',\n",
       " 'dot',\n",
       " 'drop',\n",
       " 'drop_duplicates',\n",
       " 'droplevel',\n",
       " 'dropna',\n",
       " 'dtypes',\n",
       " 'duplicated',\n",
       " 'empty',\n",
       " 'eq',\n",
       " 'equals',\n",
       " 'eval',\n",
       " 'ewm',\n",
       " 'expanding',\n",
       " 'explode',\n",
       " 'ffill',\n",
       " 'fillna',\n",
       " 'filter',\n",
       " 'first',\n",
       " 'first_valid_index',\n",
       " 'flags',\n",
       " 'floordiv',\n",
       " 'from_dict',\n",
       " 'from_records',\n",
       " 'ge',\n",
       " 'get',\n",
       " 'groupby',\n",
       " 'gt',\n",
       " 'head',\n",
       " 'hist',\n",
       " 'iat',\n",
       " 'idxmax',\n",
       " 'idxmin',\n",
       " 'iloc',\n",
       " 'index',\n",
       " 'infer_objects',\n",
       " 'info',\n",
       " 'insert',\n",
       " 'interpolate',\n",
       " 'isetitem',\n",
       " 'isin',\n",
       " 'isna',\n",
       " 'isnull',\n",
       " 'items',\n",
       " 'iterrows',\n",
       " 'itertuples',\n",
       " 'join',\n",
       " 'keys',\n",
       " 'kurt',\n",
       " 'kurtosis',\n",
       " 'last',\n",
       " 'last_valid_index',\n",
       " 'le',\n",
       " 'loc',\n",
       " 'lt',\n",
       " 'map',\n",
       " 'mask',\n",
       " 'max',\n",
       " 'mean',\n",
       " 'median',\n",
       " 'melt',\n",
       " 'memory_usage',\n",
       " 'merge',\n",
       " 'min',\n",
       " 'mod',\n",
       " 'mode',\n",
       " 'mul',\n",
       " 'multiply',\n",
       " 'name',\n",
       " 'ndim',\n",
       " 'ne',\n",
       " 'nlargest',\n",
       " 'notna',\n",
       " 'notnull',\n",
       " 'nsmallest',\n",
       " 'nunique',\n",
       " 'pad',\n",
       " 'pct_change',\n",
       " 'pipe',\n",
       " 'pivot',\n",
       " 'pivot_table',\n",
       " 'plot',\n",
       " 'pop',\n",
       " 'pow',\n",
       " 'prod',\n",
       " 'product',\n",
       " 'quantile',\n",
       " 'query',\n",
       " 'radd',\n",
       " 'rank',\n",
       " 'rdiv',\n",
       " 'reindex',\n",
       " 'reindex_like',\n",
       " 'rename',\n",
       " 'rename_axis',\n",
       " 'reorder_levels',\n",
       " 'replace',\n",
       " 'resample',\n",
       " 'reset_index',\n",
       " 'rfloordiv',\n",
       " 'rmod',\n",
       " 'rmul',\n",
       " 'rolling',\n",
       " 'round',\n",
       " 'rpow',\n",
       " 'rsub',\n",
       " 'rtruediv',\n",
       " 'salary',\n",
       " 'sample',\n",
       " 'select_dtypes',\n",
       " 'sem',\n",
       " 'set_axis',\n",
       " 'set_flags',\n",
       " 'set_index',\n",
       " 'shape',\n",
       " 'shift',\n",
       " 'size',\n",
       " 'skew',\n",
       " 'sort_index',\n",
       " 'sort_values',\n",
       " 'squeeze',\n",
       " 'stack',\n",
       " 'std',\n",
       " 'style',\n",
       " 'sub',\n",
       " 'subtract',\n",
       " 'sum',\n",
       " 'swapaxes',\n",
       " 'swaplevel',\n",
       " 'tail',\n",
       " 'take',\n",
       " 'title',\n",
       " 'to_clipboard',\n",
       " 'to_csv',\n",
       " 'to_dict',\n",
       " 'to_excel',\n",
       " 'to_feather',\n",
       " 'to_gbq',\n",
       " 'to_hdf',\n",
       " 'to_html',\n",
       " 'to_json',\n",
       " 'to_latex',\n",
       " 'to_markdown',\n",
       " 'to_numpy',\n",
       " 'to_orc',\n",
       " 'to_parquet',\n",
       " 'to_period',\n",
       " 'to_pickle',\n",
       " 'to_records',\n",
       " 'to_sql',\n",
       " 'to_stata',\n",
       " 'to_string',\n",
       " 'to_timestamp',\n",
       " 'to_xarray',\n",
       " 'to_xml',\n",
       " 'transform',\n",
       " 'transpose',\n",
       " 'truediv',\n",
       " 'truncate',\n",
       " 'tz_convert',\n",
       " 'tz_localize',\n",
       " 'unstack',\n",
       " 'update',\n",
       " 'value_counts',\n",
       " 'values',\n",
       " 'var',\n",
       " 'where',\n",
       " 'xs']"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dir(employees)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   name  age  salary title\n",
      "0  john   23   23333   CFO\n",
      "1   bob   45   43555    VP\n",
      "2   dan   12   90000   CTO\n"
     ]
    }
   ],
   "source": [
    "print(employees)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Just like Excel spreadsheets, dataframes are made up of <b>rows</b> and <b>columns</b>. Each column will have the same data type (all ints, all floats, all strings, etc.).\n",
    "\n",
    "We can then set a column (or multiple columns) as an <b>index</b> that we can use as a shorthand."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "      age  salary title\n",
      "name                   \n",
      "john   23   23333   CFO\n",
      "bob    45   43555    VP\n",
      "dan    12   90000   CTO\n"
     ]
    }
   ],
   "source": [
    "employees.set_index(\"name\",inplace=True)\n",
    "# The inplace argument above means we're replacing\n",
    "# our 'default' index with our new index.\n",
    "\n",
    "print(employees)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Index(['john', 'bob', 'dan'], dtype='object', name='name')\n",
      "Index(['age', 'salary', 'title'], dtype='object')\n"
     ]
    }
   ],
   "source": [
    "print(employees.index)\n",
    "print(employees.columns)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can then use the <b>loc[]</b> function to access a group of rows and columns by a particular label."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "age          23\n",
       "salary    23333\n",
       "title       CFO\n",
       "Name: john, dtype: object"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "employees.loc[\"john\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "age          12\n",
       "salary    90000\n",
       "title       CTO\n",
       "Name: dan, dtype: object"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Similarly, we can use 'iloc[]' to refer to a particular index.\n",
    "employees.iloc[2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It's also possible to create subsets of dataframes based on their values."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "      age  salary title\n",
      "name                   \n",
      "bob    45   43555    VP\n"
     ]
    }
   ],
   "source": [
    "# Let's only look at employees older than 30.\n",
    "print(employees[employees.age>30])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "name\n",
      "john    False\n",
      "bob      True\n",
      "dan     False\n",
      "Name: title, dtype: bool\n"
     ]
    }
   ],
   "source": [
    "# Let's look at who's a VP and who isn't.\n",
    "print(employees['title'] == 'VP')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "      age  salary title\n",
      "name                   \n",
      "john   22   23333   CFO\n",
      "bob    45   43555    VP\n",
      "dan    12   90000   CTO\n"
     ]
    }
   ],
   "source": [
    "# We can also easily set values or add new columns.\n",
    "employees.loc['john','age'] = 22\n",
    "print(employees)\n",
    "# Change John's age to 22.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "      age  salary title      city\n",
      "name                             \n",
      "john   22   23333   CFO  montreal\n",
      "bob    45   43555    VP  montreal\n",
      "dan    12   90000   CTO  montreal\n"
     ]
    }
   ],
   "source": [
    "# Let's say we now have information about what city\n",
    "# everyone's in and we want to add that where we have it.\n",
    "employees['city'] = 'montreal'\n",
    "print(employees)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "      age  salary title      city\n",
      "name                             \n",
      "john   22   23333   CFO   toronto\n",
      "bob    45   43555    VP  montreal\n",
      "dan    12   90000   CTO  montreal\n"
     ]
    }
   ],
   "source": [
    "# Whoops, Diane's moved to Toronto!\n",
    "employees.loc['john','city'] = 'toronto'\n",
    "print(employees)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The <b>describe()</b> function is a helpful summary of statistics."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "count        3.000000\n",
       "mean     52296.000000\n",
       "std      34182.247337\n",
       "min      23333.000000\n",
       "25%      33444.000000\n",
       "50%      43555.000000\n",
       "75%      66777.500000\n",
       "max      90000.000000\n",
       "Name: salary, dtype: float64"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# employees.age.describe()\n",
    "employees.salary.describe()\n",
    "# WHAT"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "      age  salary title      city\n",
      "name                             \n",
      "john   22   24333   CFO   toronto\n",
      "bob    45   44555    VP  montreal\n",
      "dan    12   91000   CTO  montreal\n"
     ]
    }
   ],
   "source": [
    "# We can also easily do mathematical operations.\n",
    "\n",
    "employees.salary = employees.salary + 1000\n",
    "print(employees)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "title\n",
       "CFO    1\n",
       "VP     1\n",
       "CTO    1\n",
       "Name: count, dtype: int64"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Or use things like value counts!\n",
    "\n",
    "employees.title.value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04',\n",
       "               '2021-01-05', '2021-01-06', '2021-01-07', '2021-01-08',\n",
       "               '2021-01-09', '2021-01-10', '2021-01-11', '2021-01-12'],\n",
       "              dtype='datetime64[ns]', freq='D')"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Pandas can also be used to create some useful date ranges!\n",
    "pd.date_range('1/1/2021','1/12/2021')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2>14.2 Pandas Examples</h2>\n",
    "\n",
    "You'll need to re-run these lines of code to clear out all the changes\n",
    "we made above..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'my_dict' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m/Users/nik/data/python/notebooks/Week 06 W.ipynb Cell 30\u001b[0m line \u001b[0;36m1\n\u001b[0;32m----> <a href='vscode-notebook-cell:/Users/nik/data/python/notebooks/Week%2006%20W.ipynb#X41sZmlsZQ%3D%3D?line=0'>1</a>\u001b[0m employees \u001b[39m=\u001b[39m pd\u001b[39m.\u001b[39mDataFrame(my_dict)\n\u001b[1;32m      <a href='vscode-notebook-cell:/Users/nik/data/python/notebooks/Week%2006%20W.ipynb#X41sZmlsZQ%3D%3D?line=1'>2</a>\u001b[0m employees\u001b[39m.\u001b[39mset_index(\u001b[39m'\u001b[39m\u001b[39mname\u001b[39m\u001b[39m'\u001b[39m, inplace\u001b[39m=\u001b[39m\u001b[39mTrue\u001b[39;00m)\n",
      "\u001b[0;31mNameError\u001b[0m: name 'my_dict' is not defined"
     ]
    }
   ],
   "source": [
    "employees = pd.DataFrame(my_dict)\n",
    "employees.set_index('name', inplace=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<b>1. Promote Ashley to CEO.</b>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<b>2. Using methods you learned in this lecture, find the mean and standard deviation of salaries.</b>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<b>3. A year has passed! Increase everyone's ages by 1.</b>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2>14.3 Pandas With Atmospheric Data</h2>\n",
    "\n",
    "Let's use a real-life example! This is information from Chris McCray at McGill: Daily weather data for Montreal from 1871-2019. Pandas has a <b>read_csv()</b> function that will come in handy here."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/var/folders/0x/8vc0k5b97mq8hxcghjr_nb300000gn/T/ipykernel_61695/2319455187.py:3: DtypeWarning: Columns (24,25,26) have mixed types. Specify dtype option on import or set low_memory=False.\n",
      "  mtl_weather = pd.read_csv('http://www.cdmccray.com/python_tutorial/pandas/montreal_daily_weather.csv')\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "\n",
    "mtl_weather = pd.read_csv('http://www.cdmccray.com/python_tutorial/pandas/montreal_daily_weather.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Index(['Date/Time', 'Year', 'Month', 'Day', 'Data Quality', 'Max Temp (°C)',\n",
      "       'Max Temp Flag', 'Min Temp (°C)', 'Min Temp Flag', 'Mean Temp (°C)',\n",
      "       'Mean Temp Flag', 'Heat Deg Days (°C)', 'Heat Deg Days Flag',\n",
      "       'Cool Deg Days (°C)', 'Cool Deg Days Flag', 'Total Rain (mm)',\n",
      "       'Total Rain Flag', 'Total Snow (cm)', 'Total Snow Flag',\n",
      "       'Total Precip (mm)', 'Total Precip Flag', 'Snow on Grnd (cm)',\n",
      "       'Snow on Grnd Flag', 'Dir of Max Gust (10s deg)',\n",
      "       'Dir of Max Gust Flag', 'Spd of Max Gust (km/h)',\n",
      "       'Spd of Max Gust Flag', 'Date', 'season'],\n",
      "      dtype='object')\n"
     ]
    }
   ],
   "source": [
    "print(mtl_weather.columns)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's set the index to the date of observation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "mtl_weather.set_index('Date/Time',inplace=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<b>Grouping</b> is a useful feature within Pandas that lets us do the following:\n",
    "<ul>\n",
    "    <li>Split the data into groups based on some criteria.</li>\n",
    "    <li>Apply a function to each group independently.</li>\n",
    "    <li>Combine the results into a data structure.</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Year\n",
      "1871    184\n",
      "1872    366\n",
      "1873    334\n",
      "1874    365\n",
      "1875    365\n",
      "       ... \n",
      "2015    358\n",
      "2016    360\n",
      "2017    351\n",
      "2018    357\n",
      "2019     74\n",
      "Name: Max Temp (°C), Length: 149, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "# As an example, let's count how much temperature data is available for each year.\n",
    "\n",
    "a = mtl_weather.groupby('Year').count()['Max Temp (°C)']\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='Year'>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 28748 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "a.plot()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Okay, so there's a lot of missing data in the 90s! We can actually remove all rows with missing data by using <b>dropna()</b>. Since there's probably a lot of data missing, let's specify that we're only removing the rows that have missing temperature data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(54421, 28)\n",
      "(52456, 28)\n"
     ]
    }
   ],
   "source": [
    "print(mtl_weather.shape)\n",
    "mtl_weather.dropna(subset=['Max Temp (°C)'], inplace=True)\n",
    "print(mtl_weather.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also use <b>groupby()</b> to calculate the average temperature for each year!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='Year'>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 88540 characters]",
      "text/plain": [
       "<Figure size 2500x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "mtl_weather.groupby('Year')['Mean Temp (°C)'].mean().plot(figsize=(25,5))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Okay, well, there's obviously something suspicious going on here - it's not that cold, even in Montreal! Note that these are years where a lot of data is missing - it looks like most of that data's from the warm season.\n",
    "\n",
    "How would you handle this kind of problem?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='Year'>"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 29092 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "yearlycounts = mtl_weather.groupby('Year').count()['Mean Temp (°C)']\n",
    "yearlycounts.plot()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's set our threshold to about 350 days."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Index([1872, 1874, 1875, 1876, 1877, 1878, 1879, 1880, 1881, 1882,\n",
      "       ...\n",
      "       2008, 2009, 2010, 2011, 2012, 2013, 2015, 2016, 2017, 2018],\n",
      "      dtype='int64', name='Year', length=135)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='Year'>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 88540 characters]",
      "text/plain": [
       "<Figure size 2500x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "goodyears = yearlycounts[yearlycounts>350].index\n",
    "print(goodyears)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can now subset the dataframe to only include data from our good years using the <b>isin()</b> function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='Year'>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 113924 characters]",
      "text/plain": [
       "<Figure size 2500x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "mtl_weather = mtl_weather[mtl_weather.Year.isin(goodyears)]\n",
    "mtl_weather.groupby('Year')['Mean Temp (°C)'].mean().plot(figsize=(25,5))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It's also very easy to get extreme values from the dataset. The <b>nsmallest()</b> function will list the smallest values, and the <b>nlargest()</b> function will list the largest."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Date/Time\n",
      "1933-12-29   -33.9\n",
      "1981-01-04   -33.5\n",
      "1943-02-15   -33.3\n",
      "1914-01-13   -32.8\n",
      "1914-02-11   -32.8\n",
      "Name: Min Temp (°C), dtype: float64\n"
     ]
    }
   ],
   "source": [
    "print(mtl_weather['Min Temp (°C)'].nsmallest())"
   ]
  },
  {
   "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 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>Year</th>\n",
       "      <th>Month</th>\n",
       "      <th>Day</th>\n",
       "      <th>Data Quality</th>\n",
       "      <th>Max Temp (°C)</th>\n",
       "      <th>Min Temp (°C)</th>\n",
       "      <th>Mean Temp (°C)</th>\n",
       "      <th>Heat Deg Days (°C)</th>\n",
       "      <th>Cool Deg Days (°C)</th>\n",
       "      <th>Total Rain (mm)</th>\n",
       "      <th>Total Snow (cm)</th>\n",
       "      <th>Total Precip (mm)</th>\n",
       "      <th>Snow on Grnd (cm)</th>\n",
       "      <th>Dir of Max Gust (10s deg)</th>\n",
       "      <th>season</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>49226.000000</td>\n",
       "      <td>49226.000000</td>\n",
       "      <td>49226.000000</td>\n",
       "      <td>0.0</td>\n",
       "      <td>49226.000000</td>\n",
       "      <td>49215.000000</td>\n",
       "      <td>49215.000000</td>\n",
       "      <td>49215.000000</td>\n",
       "      <td>49215.000000</td>\n",
       "      <td>41958.000000</td>\n",
       "      <td>41949.000000</td>\n",
       "      <td>48913.000000</td>\n",
       "      <td>12384.000000</td>\n",
       "      <td>1992.000000</td>\n",
       "      <td>49226.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>1941.422480</td>\n",
       "      <td>6.522468</td>\n",
       "      <td>15.725287</td>\n",
       "      <td>NaN</td>\n",
       "      <td>10.807128</td>\n",
       "      <td>2.680293</td>\n",
       "      <td>6.753986</td>\n",
       "      <td>12.040049</td>\n",
       "      <td>0.794034</td>\n",
       "      <td>2.111869</td>\n",
       "      <td>0.736919</td>\n",
       "      <td>2.901108</td>\n",
       "      <td>10.154797</td>\n",
       "      <td>20.743474</td>\n",
       "      <td>1941.841385</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>41.283202</td>\n",
       "      <td>3.448537</td>\n",
       "      <td>8.799889</td>\n",
       "      <td>NaN</td>\n",
       "      <td>12.444379</td>\n",
       "      <td>11.722607</td>\n",
       "      <td>11.986670</td>\n",
       "      <td>11.006062</td>\n",
       "      <td>1.850957</td>\n",
       "      <td>5.781769</td>\n",
       "      <td>2.854098</td>\n",
       "      <td>6.503921</td>\n",
       "      <td>19.577769</td>\n",
       "      <td>11.753323</td>\n",
       "      <td>41.286312</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>1872.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>NaN</td>\n",
       "      <td>-28.900000</td>\n",
       "      <td>-33.900000</td>\n",
       "      <td>-31.400000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1872.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>1906.000000</td>\n",
       "      <td>4.000000</td>\n",
       "      <td>8.000000</td>\n",
       "      <td>NaN</td>\n",
       "      <td>1.100000</td>\n",
       "      <td>-6.100000</td>\n",
       "      <td>-2.500000</td>\n",
       "      <td>0.700000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>14.000000</td>\n",
       "      <td>1907.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>1940.000000</td>\n",
       "      <td>7.000000</td>\n",
       "      <td>16.000000</td>\n",
       "      <td>NaN</td>\n",
       "      <td>11.700000</td>\n",
       "      <td>3.800000</td>\n",
       "      <td>7.700000</td>\n",
       "      <td>10.300000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>21.500000</td>\n",
       "      <td>1940.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>1974.000000</td>\n",
       "      <td>10.000000</td>\n",
       "      <td>23.000000</td>\n",
       "      <td>NaN</td>\n",
       "      <td>21.700000</td>\n",
       "      <td>12.800000</td>\n",
       "      <td>17.300000</td>\n",
       "      <td>20.500000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.800000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>2.500000</td>\n",
       "      <td>10.000000</td>\n",
       "      <td>33.000000</td>\n",
       "      <td>1974.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>2018.000000</td>\n",
       "      <td>12.000000</td>\n",
       "      <td>31.000000</td>\n",
       "      <td>NaN</td>\n",
       "      <td>36.600000</td>\n",
       "      <td>26.100000</td>\n",
       "      <td>30.300000</td>\n",
       "      <td>49.400000</td>\n",
       "      <td>12.300000</td>\n",
       "      <td>90.400000</td>\n",
       "      <td>46.500000</td>\n",
       "      <td>94.700000</td>\n",
       "      <td>145.000000</td>\n",
       "      <td>36.000000</td>\n",
       "      <td>2019.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               Year         Month           Day  Data Quality  Max Temp (°C)  \\\n",
       "count  49226.000000  49226.000000  49226.000000           0.0   49226.000000   \n",
       "mean    1941.422480      6.522468     15.725287           NaN      10.807128   \n",
       "std       41.283202      3.448537      8.799889           NaN      12.444379   \n",
       "min     1872.000000      1.000000      1.000000           NaN     -28.900000   \n",
       "25%     1906.000000      4.000000      8.000000           NaN       1.100000   \n",
       "50%     1940.000000      7.000000     16.000000           NaN      11.700000   \n",
       "75%     1974.000000     10.000000     23.000000           NaN      21.700000   \n",
       "max     2018.000000     12.000000     31.000000           NaN      36.600000   \n",
       "\n",
       "       Min Temp (°C)  Mean Temp (°C)  Heat Deg Days (°C)  Cool Deg Days (°C)  \\\n",
       "count   49215.000000    49215.000000        49215.000000        49215.000000   \n",
       "mean        2.680293        6.753986           12.040049            0.794034   \n",
       "std        11.722607       11.986670           11.006062            1.850957   \n",
       "min       -33.900000      -31.400000            0.000000            0.000000   \n",
       "25%        -6.100000       -2.500000            0.700000            0.000000   \n",
       "50%         3.800000        7.700000           10.300000            0.000000   \n",
       "75%        12.800000       17.300000           20.500000            0.000000   \n",
       "max        26.100000       30.300000           49.400000           12.300000   \n",
       "\n",
       "       Total Rain (mm)  Total Snow (cm)  Total Precip (mm)  Snow on Grnd (cm)  \\\n",
       "count     41958.000000     41949.000000       48913.000000       12384.000000   \n",
       "mean          2.111869         0.736919           2.901108          10.154797   \n",
       "std           5.781769         2.854098           6.503921          19.577769   \n",
       "min           0.000000         0.000000           0.000000           0.000000   \n",
       "25%           0.000000         0.000000           0.000000           0.000000   \n",
       "50%           0.000000         0.000000           0.000000           0.000000   \n",
       "75%           0.800000         0.000000           2.500000          10.000000   \n",
       "max          90.400000        46.500000          94.700000         145.000000   \n",
       "\n",
       "       Dir of Max Gust (10s deg)        season  \n",
       "count                1992.000000  49226.000000  \n",
       "mean                   20.743474   1941.841385  \n",
       "std                    11.753323     41.286312  \n",
       "min                     1.000000   1872.000000  \n",
       "25%                    14.000000   1907.000000  \n",
       "50%                    21.500000   1940.000000  \n",
       "75%                    33.000000   1974.000000  \n",
       "max                    36.000000   2019.000000  "
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mtl_weather.describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2>14.4 Take-Home Points</h2>\n",
    "<ul>\n",
    "    <li><b>Pandas</b> is a useful way of working with CSV data!</li>\n",
    "    <li>A <b>dataframe</b> is an object that contains rows and columns, much like an Excel spreadsheet.</li>\n",
    "    <li><b>loc()</b> will let you identify individual rows, columns, or values.</li>\n",
    "    <li><b>describe()</b> summarizes statistics for a specified section of a dataframe.</li>\n",
    "    <li><b>read_csv()</b> will read in a CSV file specified by a file location.</li>\n",
    "    <li><b>groupby()</b> carries out specific operations on groupings within a dataframe.</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
