Commit 57ff8482acc06369382eab4063a66356e6258929

Authored by Junghwan Park
1 parent 1ba50105eb
Exists in main

Update data_loading.ipynb

Showing 1 changed file with 29 additions and 74 deletions Inline Diff

python-notebook/data_loading.ipynb View file @ 57ff848
{ 1 1 {
"cells": [ 2 2 "cells": [
{ 3 3 {
"cell_type": "markdown", 4 4 "cell_type": "markdown",
"metadata": {}, 5 5 "metadata": {},
"source": [ 6 6 "source": [
"# Loading libraries" 7 7 "# Loading libraries"
] 8 8 ]
}, 9 9 },
{ 10 10 {
"cell_type": "code", 11 11 "cell_type": "code",
"execution_count": 17, 12 12 "execution_count": 17,
"metadata": {}, 13 13 "metadata": {},
"outputs": [], 14 14 "outputs": [],
"source": [ 15 15 "source": [
"import numpy as np\n", 16 16 "import numpy as np\n",
"import matplotlib.pyplot as plt\n", 17 17 "import matplotlib.pyplot as plt\n",
"import seaborn as sns\n", 18 18 "import seaborn as sns\n",
"from pandas import read_csv\n", 19 19 "from pandas import read_csv\n",
"import pandas as pd\n", 20 20 "import pandas as pd\n",
"import os\n", 21 21 "import os\n",
"from datetime import datetime, date, timedelta\n", 22 22 "from datetime import datetime, date, timedelta\n",
"from itertools import product\n", 23 23 "from itertools import product\n",
"# %load_ext line_profiler" 24 24 "# %load_ext line_profiler"
] 25 25 ]
}, 26 26 },
{ 27 27 {
"cell_type": "markdown", 28 28 "cell_type": "markdown",
"metadata": {}, 29 29 "metadata": {},
"source": [ 30 30 "source": [
"# Defining Functions and Adjusting Settings" 31 31 "# Defining Functions and Adjusting Settings"
] 32 32 ]
}, 33 33 },
{ 34 34 {
"cell_type": "code", 35 35 "cell_type": "code",
"execution_count": 36, 36 36 "execution_count": 36,
"metadata": {}, 37 37 "metadata": {},
"outputs": [], 38 38 "outputs": [],
"source": [ 39 39 "source": [
"pd.options.mode.chained_assignment = None\n", 40 40 "pd.options.mode.chained_assignment = None\n",
"\n", 41 41 "\n",
"def get_date(x):\n", 42 42 "def get_date(x):\n",
" return date(x.year, x.month, x.day)\n", 43 43 " return date(x.year, x.month, x.day)\n",
"\n", 44 44 "\n",
"def get_minute_index(x):\n", 45 45 "def get_minute_index(x):\n",
" return (x.hour * 60) + x.minute\n", 46 46 " return (x.hour * 60) + x.minute\n",
"\n", 47 47 "\n",
"\n", 48 48 "\n",
"# cut off values that are not in the range of the data\n", 49 49 "# cut off values that are not in the range of the data\n",
"THRESHOLD_OF_DAYS_PER_USER = 10\n", 50 50 "THRESHOLD_OF_DAYS_PER_USER = 10\n",
"\n", 51 51 "\n",
"# cut off values for the number of consecutive minutes for a walk\n", 52 52 "# cut off values for the number of consecutive minutes for a walk\n",
"MINIMUM_NUMBER_OF_MINUTES_FOR_A_WALK = 5\n", 53 53 "MINIMUM_NUMBER_OF_MINUTES_FOR_A_WALK = 5\n",
"\n", 54 54 "\n",
"# cut off values for the number of steps per minute for an active minute\n", 55 55 "# cut off values for the number of steps per minute for an active minute\n",
"MINIMUM_STEPS_PER_MINUTE = 60\n" 56 56 "MINIMUM_STEPS_PER_MINUTE = 60\n"
] 57 57 ]
}, 58 58 },
{ 59 59 {
"cell_type": "markdown", 60 60 "cell_type": "markdown",
"metadata": {}, 61 61 "metadata": {},
"source": [ 62 62 "source": [
"# Loading data files" 63 63 "# Loading data files"
] 64 64 ]
}, 65 65 },
{ 66 66 {
"cell_type": "code", 67 67 "cell_type": "code",
"execution_count": 5, 68 68 "execution_count": 5,
"metadata": {}, 69 69 "metadata": {},
"outputs": [], 70 70 "outputs": [],
"source": [ 71 71 "source": [
"data_dir = '../data'\n", 72 72 "data_dir = '../data'\n",
"\n", 73 73 "\n",
"daily = read_csv(os.path.join(data_dir, 'daily.csv'))\n", 74 74 "daily = read_csv(os.path.join(data_dir, 'daily.csv'))\n",
"dose = read_csv(os.path.join(data_dir, 'dose.csv'))\n", 75 75 "dose = read_csv(os.path.join(data_dir, 'dose.csv'))\n",
"jawbone = read_csv(os.path.join(data_dir, 'jawbone.csv'), low_memory=False)\n" 76 76 "jawbone = read_csv(os.path.join(data_dir, 'jawbone.csv'), low_memory=False)\n"
] 77 77 ]
}, 78 78 },
{ 79 79 {
"cell_type": "markdown", 80 80 "cell_type": "markdown",
"metadata": {}, 81 81 "metadata": {},
"source": [ 82 82 "source": [
"# Preprocessing\n", 83 83 "# Preprocessing\n",
"## Picking up the variables" 84 84 "## Picking up the variables"
] 85 85 ]
}, 86 86 },
{ 87 87 {
"cell_type": "code", 88 88 "cell_type": "code",
"execution_count": 6, 89 89 "execution_count": 6,
"metadata": {}, 90 90 "metadata": {},
"outputs": [], 91 91 "outputs": [],
"source": [ 92 92 "source": [
"# Column names of jawbone data\n", 93 93 "# Column names of jawbone data\n",
"# 'Var1', 'user', 'start_datetime', 'end_datetime', 'timezone', 'userid',\n", 94 94 "# 'Var1', 'user', 'start_datetime', 'end_datetime', 'timezone', 'userid',\n",
"# 'steps', 'gmtoff', 'tz', 'start_date', 'end_date', 'start_utime',\n", 95 95 "# 'steps', 'gmtoff', 'tz', 'start_date', 'end_date', 'start_utime',\n",
"# 'end_utime', 'start_udate', 'end_udate', 'intake_date', 'intake_utime',\n", 96 96 "# 'end_utime', 'start_udate', 'end_udate', 'intake_date', 'intake_utime',\n",
"# 'intake_tz', 'intake_gmtoff', 'intake_hour', 'intake_min',\n", 97 97 "# 'intake_tz', 'intake_gmtoff', 'intake_hour', 'intake_min',\n",
"# 'intake_slot', 'travel_start', 'travel_end', 'exit_date',\n", 98 98 "# 'intake_slot', 'travel_start', 'travel_end', 'exit_date',\n",
"# 'dropout_date', 'last_date', 'last_utime', 'last_tz', 'last_gmtoff',\n", 99 99 "# 'dropout_date', 'last_date', 'last_utime', 'last_tz', 'last_gmtoff',\n",
"# 'last_hour', 'last_min', 'start_utime_local', 'end_utime_local'\n", 100 100 "# 'last_hour', 'last_min', 'start_utime_local', 'end_utime_local'\n",
"\n", 101 101 "\n",
"\n", 102 102 "\n",
"# duplicate jawbone data\n", 103 103 "# duplicate jawbone data\n",
"jawbone2 = jawbone.copy(deep=True)\n", 104 104 "jawbone2 = jawbone.copy(deep=True)\n",
"\n", 105 105 "\n",
"# convert string datetimes to actual datetime objects\n", 106 106 "# convert string datetimes to actual datetime objects\n",
"jawbone2[\"start_utime_local\"] = pd.to_datetime(\n", 107 107 "jawbone2[\"start_utime_local\"] = pd.to_datetime(\n",
" jawbone2[\"start_utime_local\"], format=\"%Y-%m-%d %H:%M:%S\")\n", 108 108 " jawbone2[\"start_utime_local\"], format=\"%Y-%m-%d %H:%M:%S\")\n",
"jawbone2[\"start_datetime\"] = pd.to_datetime(\n", 109 109 "jawbone2[\"start_datetime\"] = pd.to_datetime(\n",
" jawbone2[\"start_datetime\"], format=\"%Y-%m-%d %H:%M:%S\")\n", 110 110 " jawbone2[\"start_datetime\"], format=\"%Y-%m-%d %H:%M:%S\")\n",
"\n", 111 111 "\n",
"# calculate the timezone offset\n", 112 112 "# calculate the timezone offset\n",
"jawbone2[\"tz_offset\"] = jawbone2[\"start_datetime\"] - \\\n", 113 113 "jawbone2[\"tz_offset\"] = jawbone2[\"start_datetime\"] - \\\n",
" jawbone2[\"start_utime_local\"]\n", 114 114 " jawbone2[\"start_utime_local\"]\n",
"\n", 115 115 "\n",
"\n", 116 116 "\n",
"# selecting only important columns\n", 117 117 "# selecting only important columns\n",
"jawbone3 = jawbone2[[\"user\", \"start_utime_local\",\n", 118 118 "jawbone3 = jawbone2[[\"user\", \"start_utime_local\",\n",
" \"end_utime_local\", \"tz_offset\", \"steps\"]]\n", 119 119 " \"end_utime_local\", \"tz_offset\", \"steps\"]]\n",
"\n", 120 120 "\n",
"# picking up the local date\n", 121 121 "# picking up the local date\n",
"jawbone3[\"local_date\"] = jawbone3[\"start_utime_local\"].apply(get_date)\n", 122 122 "jawbone3[\"local_date\"] = jawbone3[\"start_utime_local\"].apply(get_date)\n",
"\n", 123 123 "\n",
"# picking up the local minute index\n", 124 124 "# picking up the local minute index\n",
"jawbone3[\"local_minute_index\"] = jawbone3[\"start_utime_local\"].apply(\n", 125 125 "jawbone3[\"local_minute_index\"] = jawbone3[\"start_utime_local\"].apply(\n",
" get_minute_index)\n" 126 126 " get_minute_index)\n"
] 127 127 ]
}, 128 128 },
{ 129 129 {
"cell_type": "markdown", 130 130 "cell_type": "markdown",
"metadata": {}, 131 131 "metadata": {},
"source": [ 132 132 "source": [
"## Making a key info database" 133 133 "## Making a key info database"
] 134 134 ]
}, 135 135 },
{ 136 136 {
"cell_type": "code", 137 137 "cell_type": "code",
"execution_count": 7, 138 138 "execution_count": 7,
"metadata": {}, 139 139 "metadata": {},
"outputs": [], 140 140 "outputs": [],
"source": [ 141 141 "source": [
"# picking up the user - date data\n", 142 142 "# picking up the user - date data\n",
"user_date = jawbone3[[\"user\", \"local_date\"]].drop_duplicates()" 143 143 "user_date = jawbone3[[\"user\", \"local_date\"]].drop_duplicates()"
] 144 144 ]
}, 145 145 },
{ 146 146 {
"cell_type": "markdown", 147 147 "cell_type": "markdown",
"metadata": {}, 148 148 "metadata": {},
"source": [ 149 149 "source": [
"## Removing users with too small amount of data" 150 150 "## Removing users with too small amount of data"
] 151 151 ]
}, 152 152 },
{ 153 153 {
"cell_type": "code", 154 154 "cell_type": "code",
"execution_count": 13, 155 155 "execution_count": 13,
"metadata": {}, 156 156 "metadata": {},
"outputs": [ 157 157 "outputs": [
{ 158 158 {
"name": "stdout", 159 159 "name": "stdout",
"output_type": "stream", 160 160 "output_type": "stream",
"text": [ 161 161 "text": [
"Threshold: 10\n", 162 162 "Threshold: 10\n",
"Users to be removed:[12, 36, 38]\n", 163 163 "Users to be removed:[12, 36, 38]\n",
"Shape Change: 258889 -> 258363 (-526, -0.2%)\n" 164 164 "Shape Change: 258889 -> 258363 (-526, -0.2%)\n"
] 165 165 ]
}, 166 166 },
{ 167 167 {
"data": { 168 168 "data": {
"image/png": "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", 169 169 "image/png": "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",
"text/plain": [ 170 170 "text/plain": [
"<Figure size 432x288 with 1 Axes>" 171 171 "<Figure size 432x288 with 1 Axes>"
] 172 172 ]
}, 173 173 },
"metadata": {}, 174 174 "metadata": {},
"output_type": "display_data" 175 175 "output_type": "display_data"
} 176 176 }
], 177 177 ],
"source": [ 178 178 "source": [
"# making a stat of the number of days per user\n", 179 179 "# making a stat of the number of days per user\n",
"stat_user = user_date.groupby(['user'])['local_date'].nunique().sort_values()\n", 180 180 "stat_user = user_date.groupby(['user'])['local_date'].nunique().sort_values()\n",
"\n", 181 181 "\n",
"ax = plt.figure()\n", 182 182 "ax = plt.figure()\n",
"ax.patch.set_facecolor('white')\n", 183 183 "ax.patch.set_facecolor('white')\n",
"ax = sns.histplot(stat_user)\n", 184 184 "ax = sns.histplot(stat_user)\n",
"ax.set_title('Distribution of number of days per user')\n", 185 185 "ax.set_title('Distribution of number of days per user')\n",
"ax.set_xlabel('Number of days')\n", 186 186 "ax.set_xlabel('Number of days')\n",
"ax.set_ylabel('Frequency')\n", 187 187 "ax.set_ylabel('Frequency')\n",
"\n", 188 188 "\n",
"\n", 189 189 "\n",
"# filter out users that have less days of data than THRESHOLD_OF_DAYS_PER_USER\n", 190 190 "# filter out users that have less days of data than THRESHOLD_OF_DAYS_PER_USER\n",
"users_to_be_removed = stat_user[stat_user < THRESHOLD_OF_DAYS_PER_USER].index\n", 191 191 "users_to_be_removed = stat_user[stat_user < THRESHOLD_OF_DAYS_PER_USER].index\n",
"\n", 192 192 "\n",
"print(\"Threshold: {}\".format(THRESHOLD_OF_DAYS_PER_USER))\n", 193 193 "print(\"Threshold: {}\".format(THRESHOLD_OF_DAYS_PER_USER))\n",
"print(\"Users to be removed:{}\".format(list(users_to_be_removed)))\n", 194 194 "print(\"Users to be removed:{}\".format(list(users_to_be_removed)))\n",
"\n", 195 195 "\n",
"jawbone4 = jawbone3[~jawbone3[\"user\"].isin(users_to_be_removed)]\n", 196 196 "jawbone4 = jawbone3[~jawbone3[\"user\"].isin(users_to_be_removed)]\n",
"\n", 197 197 "\n",
"user_date2 = user_date[~user_date[\"user\"].isin(users_to_be_removed)]\n", 198 198 "user_date2 = user_date[~user_date[\"user\"].isin(users_to_be_removed)]\n",
"\n", 199 199 "\n",
"# printing the amount of data removed\n", 200 200 "# printing the amount of data removed\n",
"jawbone3_count, _ = jawbone3.shape\n", 201 201 "jawbone3_count, _ = jawbone3.shape\n",
"jawbone4_count, _ = jawbone4.shape\n", 202 202 "jawbone4_count, _ = jawbone4.shape\n",
"\n", 203 203 "\n",
"print(\"Shape Change: {} -> {} (-{}, -{}%)\".format(\n", 204 204 "print(\"Shape Change: {} -> {} (-{}, -{}%)\".format(\n",
" jawbone3_count, \n", 205 205 " jawbone3_count, \n",
" jawbone4_count, \n", 206 206 " jawbone4_count, \n",
" jawbone3_count - jawbone4_count, \n", 207 207 " jawbone3_count - jawbone4_count, \n",
" round((jawbone3_count - jawbone4_count) / jawbone3_count * 100, 2)\n", 208 208 " round((jawbone3_count - jawbone4_count) / jawbone3_count * 100, 2)\n",
" )\n", 209 209 " )\n",
")" 210 210 ")"
] 211 211 ]
}, 212 212 },
{ 213 213 {
"cell_type": "markdown", 214 214 "cell_type": "markdown",
"metadata": {}, 215 215 "metadata": {},
"source": [ 216 216 "source": [
"## Find consecutive minute walks" 217 217 "## Find consecutive minute walks"
] 218 218 ]
}, 219 219 },
{ 220 220 {
"cell_type": "code", 221 221 "cell_type": "code",
"execution_count": 37, 222 222 "execution_count": 37,
"metadata": {}, 223 223 "metadata": {},
"outputs": [ 224 224 "outputs": [
{ 225 225 {
"name": "stdout", 226 226 "name": "stdout",
"output_type": "stream", 227 227 "output_type": "stream",
"text": [ 228 228 "text": [
"Iteration: 0, length: 377396\n", 229 229 "Iteration: 0, length: 377396\n",
"Iteration: 1, length: 229752\n", 230 230 "Iteration: 1, length: 229752\n",
"Iteration: 2, length: 170648\n", 231 231 "Iteration: 2, length: 170648\n",
"Iteration: 3, length: 137484\n", 232 232 "Iteration: 3, length: 137484\n",
"Iteration: 4, length: 178268\n", 233 233 "Iteration: 4, length: 178268\n",
"Final, length: 94884\n" 234 234 "Final, length: 94884\n"
] 235 235 ]
} 236 236 }
], 237 237 ],
"source": [ 238 238 "source": [
"# prepare the data for the walk calculation\n", 239 239 "# prepare the data for the walk calculation\n",
"current_vector = jawbone4[[\"user\", \"local_date\", \"local_minute_index\", \"steps\"]]\n", 240 240 "current_vector = jawbone4[[\"user\", \"local_date\", \"local_minute_index\", \"steps\"]]\n",
"current_vector[\"add_count\"] = 1\n", 241 241 "current_vector[\"add_count\"] = 1\n",
"current_vector = current_vector[current_vector[\"steps\"] > MINIMUM_STEPS_PER_MINUTE]\n", 242 242 "current_vector = current_vector[current_vector[\"steps\"] > MINIMUM_STEPS_PER_MINUTE]\n",
"current_vector = current_vector[[\"user\", \"local_date\", \"local_minute_index\", \"add_count\"]]\n", 243 243 "current_vector = current_vector[[\"user\", \"local_date\", \"local_minute_index\", \"add_count\"]]\n",
"\n", 244 244 "\n",
"# define an iterative walk calculation (merging consecutive active minutes)\n", 245 245 "# define an iterative walk calculation (merging consecutive active minutes)\n",
"def calculate_walk(cv):\n", 246 246 "def calculate_walk(cv):\n",
" nv = cv.copy(deep=True)\n", 247 247 " nv = cv.copy(deep=True)\n",
" nv[\"prev_minute_index\"] = nv[\"local_minute_index\"] - 1\n", 248 248 " nv[\"prev_minute_index\"] = nv[\"local_minute_index\"] - 1\n",
"\n", 249 249 "\n",
" # move midnight minutes to previous day\n", 250 250 " # move midnight minutes to previous day\n",
" nv[nv[\"prev_minute_index\"] < 0][\"local_date\"] -= timedelta(days=1)\n", 251 251 " nv[nv[\"prev_minute_index\"] < 0][\"local_date\"] -= timedelta(days=1)\n",
" nv[nv[\"prev_minute_index\"] < 0][\"prev_minute_index\"] = 1439\n", 252 252 " nv[nv[\"prev_minute_index\"] < 0][\"prev_minute_index\"] = 1439\n",
" \n", 253 253 " \n",
" nv = nv[[\"user\", \"local_date\", \"prev_minute_index\"]]\n", 254 254 " nv = nv[[\"user\", \"local_date\", \"prev_minute_index\"]]\n",
" jv = cv.merge(nv, left_on=[\"user\", \"local_date\", \"local_minute_index\"], right_on=[\"user\", \"local_date\", \"prev_minute_index\"], how=\"inner\")\n", 255 255 " jv = cv.merge(nv, left_on=[\"user\", \"local_date\", \"local_minute_index\"], right_on=[\"user\", \"local_date\", \"prev_minute_index\"], how=\"inner\")\n",
" jv[\"add_count\"] += 1\n", 256 256 " jv[\"add_count\"] += 1\n",
" jv = jv[[\"user\", \"local_date\", \"local_minute_index\", \"add_count\"]]\n", 257 257 " jv = jv[[\"user\", \"local_date\", \"local_minute_index\", \"add_count\"]]\n",
"\n", 258 258 "\n",
" return jv \n", 259 259 " return jv \n",
"\n", 260 260 "\n",
"\n", 261 261 "\n",
"# iteratively calculate the walk\n", 262 262 "# iteratively calculate the walk\n",
"for i in range(0, MINIMUM_NUMBER_OF_MINUTES_FOR_A_WALK):\n", 263 263 "for i in range(0, MINIMUM_NUMBER_OF_MINUTES_FOR_A_WALK):\n",
" print(\"Iteration: {}, length: {}\".format(i, current_vector.size))\n", 264 264 " print(\"Iteration: {}, length: {}\".format(i, current_vector.size))\n",
" new_vector = calculate_walk(current_vector)\n", 265 265 " new_vector = calculate_walk(current_vector)\n",
" current_vector = new_vector\n", 266 266 " current_vector = new_vector\n",
"\n", 267 267 "\n",
"print(\"Final, length: {}\".format(current_vector.size))\n", 268 268 "print(\"Final, length: {}\".format(current_vector.size))\n",
"\n", 269 269 "\n",
"consecutive_minutes = current_vector[[\"user\", \"local_date\", \"local_minute_index\"]].drop_duplicates()" 270 270 "consecutive_minutes = current_vector[[\"user\", \"local_date\", \"local_minute_index\"]].drop_duplicates()"
] 271 271 ]
}, 272 272 },
{ 273 273 {
"cell_type": "markdown", 274 274 "cell_type": "markdown",
"metadata": {}, 275 275 "metadata": {},
"source": [ 276 276 "source": [
"## Map consecutive minutes to 1hr and 3hr units" 277 277 "## Map consecutive minutes to 1hr and 3hr units"
] 278 278 ]
}, 279 279 },
{ 280 280 {
"cell_type": "code", 281 281 "cell_type": "code",
"execution_count": 108, 282 282 "execution_count": 110,
"metadata": {}, 283 283 "metadata": {},
"outputs": [ 284 284 "outputs": [
{ 285 285 {
"name": "stdout", 286 286 "name": "stdout",
"output_type": "stream", 287 287 "output_type": "stream",
"text": [ 288 288 "text": [
" index user local_date hour walked\n", 289 289 " index user local_date threehour walked\n",
"0 0 1 2015-07-22 8 2\n", 290 290 "0 0 1 2015-07-22 2 2\n",
"1 3 1 2015-07-22 18 2\n", 291 291 "1 3 1 2015-07-22 6 2\n",
"2 10 1 2015-07-22 19 2\n", 292 292 "2 30 1 2015-07-23 2 2\n",
"3 30 1 2015-07-23 8 2\n", 293 293 "3 50 1 2015-07-23 3 2\n",
"4 50 1 2015-07-23 9 2\n", 294 294 "4 58 1 2015-07-23 5 2\n",
" user local_date hour walked\n", 295 295 " user local_date threehour walked\n",
"0 1 2015-07-22 0 1.0\n", 296 296 "0 1 2015-07-22 0 1.0\n",
"1 1 2015-07-22 1 1.0\n", 297 297 "1 1 2015-07-22 1 1.0\n",
"2 1 2015-07-22 2 1.0\n", 298 298 "2 1 2015-07-22 2 2.0\n",
"3 1 2015-07-22 3 1.0\n", 299 299 "3 1 2015-07-22 3 1.0\n",
"4 1 2015-07-22 4 1.0\n", 300 300 "4 1 2015-07-22 4 1.0\n",
"5 1 2015-07-22 5 1.0\n", 301 301 "5 1 2015-07-22 5 1.0\n",
"6 1 2015-07-22 6 1.0\n", 302 302 "6 1 2015-07-22 6 2.0\n",
"7 1 2015-07-22 7 1.0\n", 303 303 "7 1 2015-07-22 7 1.0\n",
"8 1 2015-07-22 8 2.0\n", 304 304 "8 1 2015-07-23 0 1.0\n",
"9 1 2015-07-22 9 1.0\n", 305 305 "9 1 2015-07-23 1 1.0\n",
"10 1 2015-07-22 10 1.0\n", 306 306 "10 1 2015-07-23 2 2.0\n",
"11 1 2015-07-22 11 1.0\n", 307 307 "11 1 2015-07-23 3 2.0\n",
"12 1 2015-07-22 12 1.0\n", 308 308 "12 1 2015-07-23 4 1.0\n",
"13 1 2015-07-22 13 1.0\n", 309 309 "13 1 2015-07-23 5 2.0\n",
"14 1 2015-07-22 14 1.0\n", 310 310 "14 1 2015-07-23 6 1.0\n",
"15 1 2015-07-22 15 1.0\n", 311 311 "15 1 2015-07-23 7 1.0\n"
"16 1 2015-07-22 16 1.0\n", 312
"17 1 2015-07-22 17 1.0\n", 313
"18 1 2015-07-22 18 2.0\n", 314
"19 1 2015-07-22 19 2.0\n", 315
"20 1 2015-07-22 20 1.0\n", 316
"21 1 2015-07-22 21 1.0\n", 317
"22 1 2015-07-22 22 1.0\n", 318
"23 1 2015-07-22 23 1.0\n", 319
"24 1 2015-07-23 0 1.0\n", 320
"25 1 2015-07-23 1 1.0\n", 321
"26 1 2015-07-23 2 1.0\n", 322
"27 1 2015-07-23 3 1.0\n", 323
"28 1 2015-07-23 4 1.0\n", 324
"29 1 2015-07-23 5 1.0\n", 325
"30 1 2015-07-23 6 1.0\n", 326
"31 1 2015-07-23 7 1.0\n", 327
"32 1 2015-07-23 8 2.0\n", 328
"33 1 2015-07-23 9 2.0\n", 329
"34 1 2015-07-23 10 1.0\n", 330
"35 1 2015-07-23 11 1.0\n", 331
"36 1 2015-07-23 12 1.0\n", 332
"37 1 2015-07-23 13 1.0\n", 333
"38 1 2015-07-23 14 1.0\n", 334
"39 1 2015-07-23 15 1.0\n", 335
"40 1 2015-07-23 16 1.0\n", 336
"41 1 2015-07-23 17 1.0\n", 337
"42 1 2015-07-23 18 1.0\n", 338
"43 1 2015-07-23 19 1.0\n", 339
"44 1 2015-07-23 20 1.0\n", 340
"45 1 2015-07-23 21 1.0\n", 341
"46 1 2015-07-23 22 1.0\n", 342
"47 1 2015-07-23 23 1.0\n" 343
] 344 312 ]
} 345 313 }
], 346 314 ],
"source": [ 347 315 "source": [
"# calculate hour index and three hour index\n", 348 316 "# calculate hour index and three hour index\n",
"consecutive_minutes[\"hour\"] = np.int_(np.floor(consecutive_minutes[\"local_minute_index\"] / 60))\n", 349 317 "consecutive_minutes[\"hour\"] = np.int_(np.floor(consecutive_minutes[\"local_minute_index\"] / 60))\n",
"consecutive_minutes[\"threehour\"] = np.int_(np.floor(consecutive_minutes[\"hour\"] / 3))\n", 350 318 "consecutive_minutes[\"threehour\"] = np.int_(np.floor(consecutive_minutes[\"hour\"] / 3))\n",
"\n", 351 319 "\n",
"# calculate the number of walks per user, per hour\n", 352 320 "# calculate the number of walks per user, per hour\n",
"walk_by_hours = consecutive_minutes[[\"user\", \"local_date\", \"hour\"]].drop_duplicates().reset_index()\n", 353 321 "walk_by_hours = consecutive_minutes[[\"user\", \"local_date\", \"hour\"]].drop_duplicates().reset_index()\n",
"walk_by_hours[\"walked\"] = 2\n", 354 322 "walk_by_hours[\"walked\"] = 2\n",
"\n", 355 323 "\n",
"# calculate the number of walks per user, per three hour\n", 356 324 "# calculate the number of walks per user, per three hour\n",
"walk_by_threehours = consecutive_minutes[[\"user\", \"local_date\", \"threehour\"]].drop_duplicates().reset_index()\n", 357 325 "walk_by_threehours = consecutive_minutes[[\"user\", \"local_date\", \"threehour\"]].drop_duplicates().reset_index()\n",
"walk_by_threehours[\"walked\"] = 2\n", 358 326 "walk_by_threehours[\"walked\"] = 2\n",
"\n", 359 327 "\n",
"# generate hour vector and three hour vector\n", 360 328 "# generate hour vector and three hour vector\n",
"hours = pd.DataFrame({\"hour\": range(0,24)})\n", 361 329 "hours = pd.DataFrame({\"hour\": range(0,24)})\n",
"threehours = pd.DataFrame({\"threehour\": range(0, 8)})\n", 362 330 "threehours = pd.DataFrame({\"threehour\": range(0, 8)})\n",
"\n", 363 331 "\n",
"\n", 364 332 "\n",
"walk_by_hours = walk_by_hours[:5]\n", 365 333 "walk_by_hours = walk_by_hours[:5]\n",
"walk_by_threehours = walk_by_threehours[:5]\n", 366 334 "walk_by_threehours = walk_by_threehours[:5]\n",
"\n", 367 335 "\n",
"# generate complete product of vectors\n", 368 336 "# generate complete product of vectors\n",
"def product_df(mat1, mat2):\n", 369 337 "def product_df(mat1, mat2):\n",
" mat1 = mat1.drop_duplicates()\n", 370 338 " mat1 = mat1.drop_duplicates()\n",
" mat2 = mat2.drop_duplicates()\n", 371 339 " mat2 = mat2.drop_duplicates()\n",
"\n", 372 340 "\n",
" temp = pd.DataFrame(list(product(mat1.values, mat2.values)))\n", 373 341 " temp = pd.DataFrame(list(product(mat1.values, mat2.values)))\n",
" for i, acol in enumerate(mat1.columns):\n", 374 342 " for i, acol in enumerate(mat1.columns):\n",
" temp[acol] = temp[0].apply(lambda x: x[i])\n", 375 343 " temp[acol] = temp[0].apply(lambda x: x[i])\n",
" for i, acol in enumerate(mat2.columns):\n", 376 344 " for i, acol in enumerate(mat2.columns):\n",
" temp[acol] = temp[1].apply(lambda x: x[i])\n", 377 345 " temp[acol] = temp[1].apply(lambda x: x[i])\n",
" temp = temp.drop(columns=[0, 1])\n", 378 346 " temp = temp.drop(columns=[0, 1])\n",
" return temp\n", 379 347 " return temp\n",
"\n", 380 348 "\n",
"measured_hour = product_df(walk_by_hours[[\"user\", \"local_date\"]], hours[[\"hour\"]])\n", 381 349 "measured_hour = product_df(walk_by_hours[[\"user\", \"local_date\"]], hours[[\"hour\"]])\n",
"measured_threehour = product_df(walk_by_threehours[[\"user\", \"local_date\"]], threehours[[\"threehour\"]])\n", 382 350 "measured_threehour = product_df(walk_by_threehours[[\"user\", \"local_date\"]], threehours[[\"threehour\"]])\n",
"\n", 383 351 "\n",
"\n", 384 352 "# pad the hourly walk data (fill in missing hours with 1s)\n",
"\n", 385
"print(walk_by_threehours)\n", 386
"\n", 387
"padded_hours = walk_by_hours.merge(measured_hour, on=[\"user\", \"local_date\", \"hour\"], how=\"right\")\n", 388 353 "padded_hours = walk_by_hours.merge(measured_hour, on=[\"user\", \"local_date\", \"hour\"], how=\"right\")\n",
"padded_hours = padded_hours[[\"user\", \"local_date\", \"hour\", \"walked\"]]\n", 389 354 "padded_hours = padded_hours[[\"user\", \"local_date\", \"hour\", \"walked\"]]\n",
"padded_hours = padded_hours.fillna(1)\n", 390 355 "padded_hours = padded_hours.fillna(1)\n",
"\n", 391 356 "\n",
"padded_threehours = walk_by_threehours.merge(measured_threehour, on=[\"user\", \"local_date\", \"hour\"], how=\"right\")\n", 392 357 "# pad the walk data with 3 hours unit (fill in missing hours with 1s)\n",
"padded_threehours = padded_threehours[[\"user\", \"local_date\", \"hour\", \"walked\"]]\n", 393 358 "padded_threehours = walk_by_threehours.merge(measured_threehour, on=[\"user\", \"local_date\", \"threehour\"], how=\"right\")\n",
"padded_threehours = padded_threehours.fillna(1)\n", 394 359 "padded_threehours = padded_threehours[[\"user\", \"local_date\", \"threehour\", \"walked\"]]\n",
"\n", 395 360 "padded_threehours = padded_threehours.fillna(1)"
"print(padded_threehours)\n", 396
"\n", 397
"# walk_by_hour = consecutive_minutes.groupby([\"user\", \"local_date\", \"hour\"])[\"add_count\"].sum().reset_index()\n", 398
"# walk_by_threehour = consecutive_minutes.groupby([\"user\", \"local_date\", \"threehour\"])[\"add_count\"].sum().reset_index()\n", 399
"\n", 400
"# walk_by_hour[\"walked\"] = 1\n", 401
"# walk_by_threehour[\"walked\"] = 1\n", 402
"\n", 403
"\n", 404
"# hours2 = walk_by_hour.merge(hours, left_on=\"hour\", right_on=\"hour\", how=\"right\")\n" 405
] 406 361 ]
}, 407 362 },
{ 408 363 {
"cell_type": "code", 409 364 "cell_type": "code",
"execution_count": null, 410 365 "execution_count": null,
"metadata": {}, 411 366 "metadata": {},
"outputs": [], 412 367 "outputs": [],
"source": [ 413 368 "source": [
"\n", 414 369 "\n",
"\n", 415 370 "\n",
"standard_minute_index = pd.Series(name=\"local_minute_index\", data=np.arange(0, 1440, 1))\n", 416 371 "standard_minute_index = pd.Series(name=\"local_minute_index\", data=np.arange(0, 1440, 1))\n",
"\n", 417 372 "\n",
"a_user = users[0]\n", 418 373 "a_user = users[0]\n",
"a_date = user_date2.local_date[0]\n", 419 374 "a_date = user_date2.local_date[0]\n",
"\n", 420 375 "\n",
"a_jawbone3 = jawbone3.loc[(jawbone3.user == a_user) & (jawbone3.local_date == a_date), :]\n", 421 376 "a_jawbone3 = jawbone3.loc[(jawbone3.user == a_user) & (jawbone3.local_date == a_date), :]\n",
"\n", 422 377 "\n",
"vec = a_jawbone3[[\"local_minute_index\", \"steps\"]]\n", 423 378 "vec = a_jawbone3[[\"local_minute_index\", \"steps\"]]\n",
"\n", 424 379 "\n",
"steps = [0] * 1440\n", 425 380 "steps = [0] * 1440\n",
"\n", 426 381 "\n",
"for index, row in vec.iterrows():\n", 427 382 "for index, row in vec.iterrows():\n",
" steps[row.local_minute_index] += row.steps\n", 428 383 " steps[row.local_minute_index] += row.steps\n",
"\n", 429 384 "\n",
"print(steps)\n", 430 385 "print(steps)\n",
"steps_series = pd.Series(name=\"steps\", data=steps)\n", 431 386 "steps_series = pd.Series(name=\"steps\", data=steps)\n",
"steps_series[\"over60\"] = (steps_series > 60) * 1\n", 432 387 "steps_series[\"over60\"] = (steps_series > 60) * 1\n",
"\n", 433 388 "\n",
"steps_series[\"roll\"] = steps_series.rolling(window=5, min_periods=1).sum()\n", 434 389 "steps_series[\"roll\"] = steps_series.rolling(window=5, min_periods=1).sum()\n",
"\n", 435 390 "\n",
"steps_series.roll.plot()\n", 436 391 "steps_series.roll.plot()\n",
"\n", 437 392 "\n",
"\n" 438 393 "\n"
] 439 394 ]
} 440 395 }
], 441 396 ],
"metadata": { 442 397 "metadata": {
"interpreter": { 443 398 "interpreter": {
"hash": "80dbe1014b4652684caa329d41db00af3ae439be86b11eab7e35b518e5d8ab1a" 444 399 "hash": "80dbe1014b4652684caa329d41db00af3ae439be86b11eab7e35b518e5d8ab1a"
}, 445 400 },
"kernelspec": { 446 401 "kernelspec": {
"display_name": "Python 3.7.9 64-bit ('venv': venv)", 447 402 "display_name": "Python 3.7.9 64-bit ('venv': venv)",
"language": "python", 448 403 "language": "python",
"name": "python3" 449 404 "name": "python3"
}, 450 405 },
"language_info": { 451 406 "language_info": {
"codemirror_mode": { 452 407 "codemirror_mode": {
"name": "ipython", 453 408 "name": "ipython",
"version": 3 454 409 "version": 3
}, 455 410 },
"file_extension": ".py", 456 411 "file_extension": ".py",
"mimetype": "text/x-python", 457 412 "mimetype": "text/x-python",
"name": "python", 458 413 "name": "python",
"nbconvert_exporter": "python", 459 414 "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", 460 415 "pygments_lexer": "ipython3",
"version": "3.7.9" 461 416 "version": "3.7.9"
}, 462 417 },
"orig_nbformat": 4 463 418 "orig_nbformat": 4
}, 464 419 },
"nbformat": 4, 465 420 "nbformat": 4,
"nbformat_minor": 2 466 421 "nbformat_minor": 2
} 467 422 }
468 423