{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# загружаем основные библиотеки\n",
    "import numpy as np\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# пишем функцию, которая вычисляет \n",
    "# формулу гаверсинусов\n",
    "def haversine(lat1, lon1, lat2, lon2):\n",
    "    MILES = 3959\n",
    "    lat1, lon1, lat2, lon2 = map(np.deg2rad, [lat1, lon1, lat2, lon2])\n",
    "    dlat = lat2 - lat1 \n",
    "    dlon = lon2 - lon1 \n",
    "    a = np.sin(dlat/2)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2)**2\n",
    "    c = 2 * np.arcsin(np.sqrt(a)) \n",
    "    total_miles = MILES * c\n",
    "    return total_miles"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ean_hotel_id</th>\n",
       "      <th>name</th>\n",
       "      <th>address1</th>\n",
       "      <th>city</th>\n",
       "      <th>state_province</th>\n",
       "      <th>postal_code</th>\n",
       "      <th>latitude</th>\n",
       "      <th>longitude</th>\n",
       "      <th>star_rating</th>\n",
       "      <th>high_rate</th>\n",
       "      <th>low_rate</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>269955</td>\n",
       "      <td>Hilton Garden Inn Albany/SUNY Area</td>\n",
       "      <td>1389 Washington Ave</td>\n",
       "      <td>Albany</td>\n",
       "      <td>NY</td>\n",
       "      <td>12206</td>\n",
       "      <td>42.68751</td>\n",
       "      <td>-73.81643</td>\n",
       "      <td>3.0</td>\n",
       "      <td>154.0272</td>\n",
       "      <td>124.0216</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>113431</td>\n",
       "      <td>Courtyard by Marriott Albany Thruway</td>\n",
       "      <td>1455 Washington Avenue</td>\n",
       "      <td>Albany</td>\n",
       "      <td>NY</td>\n",
       "      <td>12206</td>\n",
       "      <td>42.68971</td>\n",
       "      <td>-73.82021</td>\n",
       "      <td>3.0</td>\n",
       "      <td>179.0100</td>\n",
       "      <td>134.0000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>108151</td>\n",
       "      <td>Radisson Hotel Albany</td>\n",
       "      <td>205 Wolf Rd</td>\n",
       "      <td>Albany</td>\n",
       "      <td>NY</td>\n",
       "      <td>12205</td>\n",
       "      <td>42.72410</td>\n",
       "      <td>-73.79822</td>\n",
       "      <td>3.0</td>\n",
       "      <td>134.1700</td>\n",
       "      <td>84.1600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>254756</td>\n",
       "      <td>Hilton Garden Inn Albany Medical Center</td>\n",
       "      <td>62 New Scotland Ave</td>\n",
       "      <td>Albany</td>\n",
       "      <td>NY</td>\n",
       "      <td>12208</td>\n",
       "      <td>42.65157</td>\n",
       "      <td>-73.77638</td>\n",
       "      <td>3.0</td>\n",
       "      <td>308.2807</td>\n",
       "      <td>228.4597</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>198232</td>\n",
       "      <td>CrestHill Suites SUNY University Albany</td>\n",
       "      <td>1415 Washington Avenue</td>\n",
       "      <td>Albany</td>\n",
       "      <td>NY</td>\n",
       "      <td>12206</td>\n",
       "      <td>42.68873</td>\n",
       "      <td>-73.81854</td>\n",
       "      <td>3.0</td>\n",
       "      <td>169.3900</td>\n",
       "      <td>89.3900</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   ean_hotel_id                                     name  \\\n",
       "0        269955       Hilton Garden Inn Albany/SUNY Area   \n",
       "1        113431     Courtyard by Marriott Albany Thruway   \n",
       "2        108151                    Radisson Hotel Albany   \n",
       "3        254756  Hilton Garden Inn Albany Medical Center   \n",
       "4        198232  CrestHill Suites SUNY University Albany   \n",
       "\n",
       "                 address1    city state_province postal_code  latitude  \\\n",
       "0     1389 Washington Ave  Albany             NY       12206  42.68751   \n",
       "1  1455 Washington Avenue  Albany             NY       12206  42.68971   \n",
       "2             205 Wolf Rd  Albany             NY       12205  42.72410   \n",
       "3     62 New Scotland Ave  Albany             NY       12208  42.65157   \n",
       "4  1415 Washington Avenue  Albany             NY       12206  42.68873   \n",
       "\n",
       "   longitude  star_rating  high_rate  low_rate  \n",
       "0  -73.81643          3.0   154.0272  124.0216  \n",
       "1  -73.82021          3.0   179.0100  134.0000  \n",
       "2  -73.79822          3.0   134.1700   84.1600  \n",
       "3  -73.77638          3.0   308.2807  228.4597  \n",
       "4  -73.81854          3.0   169.3900   89.3900  "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# загружаем данные, на которых будем тестировать \n",
    "# нашу функцию\n",
    "df = pd.read_csv('C:/data/new_york_hotels.csv', encoding='cp1252')\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Базовое итерирование"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# задаем функцию, которая просто перебирает все строки \n",
    "# и возвращает серию с расстояниями, вычисленными\n",
    "# по формуле гаверсинусов\n",
    "def haversine_looping(df):\n",
    "    distance_list = []\n",
    "    for i in range(0, len(df)):\n",
    "        d = haversine(40.671, -73.985, df.iloc[i]['latitude'], df.iloc[i]['longitude'])\n",
    "        distance_list.append(d)\n",
    "    return distance_list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "696 ms ± 53.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit\n",
    "\n",
    "# запускаем итеративную функцию haversine\n",
    "df['distance'] = haversine_looping(df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Итерирование с помощью метода .iterrows()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "215 ms ± 48.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit\n",
    "\n",
    "# запускаем итерирование с помощью\n",
    "# метода .iterrrows()\n",
    "haversine_series = []\n",
    "for index, row in df.iterrows():\n",
    "    haversine_series.append(haversine(40.671, -73.985, row['latitude'], row['longitude']))\n",
    "df['distance'] = haversine_series"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Более лучший способ итерирования с помощью метода .apply()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "81.2 ms ± 5.04 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit\n",
    "\n",
    "# применяем функцию haversine с помощью\n",
    "# метода .apply()\n",
    "df['distance'] = df.apply(lambda row: haversine(40.671, -73.985, row['latitude'],\n",
    "                                                row['longitude']), axis=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Векторизация c помощью объектов Series"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.09 ms ± 225 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit \n",
    "\n",
    "# векторизированная реализация функции haversine, \n",
    "# используем объекты Series целиком\n",
    "df['distance'] = haversine(40.671, -73.985,df['latitude'], df['longitude'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Векторизация с помощью массивов NumPy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "372 µs ± 32.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit\n",
    "\n",
    "# векторизированная реализация функции haversine, \n",
    "# используем вместо объектов Series массивы NumPy\n",
    "df['distance'] = haversine(40.671, -73.985, df['latitude'].values, df['longitude'].values)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
