Skip to content

Instantly share code, notes, and snippets.

@redpanda-ai
Created February 21, 2019 01:51
Show Gist options
  • Save redpanda-ai/588f57474bad029cfe52d0a58dfa6fd6 to your computer and use it in GitHub Desktop.
Save redpanda-ai/588f57474bad029cfe52d0a58dfa6fd6 to your computer and use it in GitHub Desktop.
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Introduction\n",
"\n",
"My friend [Johannes Giorgis] and I are developing a series of [Data Science Challenges] to help others\n",
"become better data scientists by presenting a series of challenges. Why did we do this?\n",
"\n",
"\n",
"> Because that's what heroes do!\n",
">\n",
"> --Johannes Giorgis\n",
"\n",
"I now present my response to the first challenge, Exploring the Meetup API in my the city of my choice.\n",
"\n",
"**San Francisco, CA**, I choose you!\n",
"\n",
"\n",
"\n",
"# Challenge 01: Explore the Meetup API\n",
"Use the [Meetup API] to explore meetups in your city of choice.\n",
"\n",
"\n",
"**Guide Questions**:\n",
"\n",
"Below are some guide line questions to get you started:\n",
"\n",
"- What is the largest meetup in your location of choice (city, cities, country...etc)?\n",
"- How many meetups of a certain category (e.g. Tech, Art...etc) are in your city?\n",
"- Basic statistics of meetups\n",
"\t- What is the average size of meetups?\n",
"\t- How frequently do meetups host events?\n",
"\n",
"\n",
"\n",
"\n",
"## Prerequisites:\n",
"Add a [Meetup API Key] to your environment.\n",
"\n",
"[//]: # (References)\n",
"\n",
"[Meetup API]: https://www.meetup.com/meetup_api/\n",
"[Meetup API Key]: https://secure.meetup.com/meetup_api/key/\n",
"[Johannes Giorgis]: http://johannesgiorgis.com/\n",
"[Data Science Challenges]: https://medium.com/red-panda-ai/introducing-data-science-challenges-4ae4a103d67b"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import datetime\n",
"import json\n",
"import math\n",
"import meetup.api\n",
"import os\n",
"import pprint\n",
"import requests\n",
"\n",
"import matplotlib.pyplot as plt\n",
"import pandas as pd\n",
"import numpy as np\n",
"import seaborn as sb\n",
"\n",
"from tqdm import tnrange, tqdm_notebook\n",
"\n",
"%matplotlib inline"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Double check your environment\n",
"\n",
"Nothing works without **MEETUP_API_KEY**."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"assert 'MEETUP_API_KEY' in os.environ, (\n",
" \"You need a MEETUP_API_KEY in your environment please look at the \"\n",
" \"README for instructions.\")\n",
"client = meetup.api.Client()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Categories\n",
"\n",
"There are multiple categories of groups in Meetup, let's use Python's meetup.api to [GetCategories](https://meetup-api.readthedocs.io/en/latest/meetup_api.html#meetup.api.meetup.api.Client.GetCategories)."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"%%capture --no-display\n",
"categories = client.GetCategories()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Exploring the response object\n",
"\n",
"By looking at the **meta** member of the response, we can see that there are 33 different categories."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### What are the attributes of the response object?\n",
"We can find out by using __dict__ to get the attribute dictionary. First, \n",
"let's create some helper functions"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# Helper functions\n",
"def parse_meta(response):\n",
" \"\"\"Return a vertically aligned dataframe, where each row is an element \n",
" of the response.meta dictionary\"\"\"\n",
" return pd.DataFrame.from_dict(response.meta, orient='index')\n",
"\n",
"def parse_results(response):\n",
" \"\"\"Return a horizontally aligned dataframe, where each column is an\n",
" element of the response.results dictionary \"\"\"\n",
" return pd.DataFrame.from_dict(response.results)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Now we can easily inspect our categories response object\n",
"\n",
"#### Firstly, let's look at the meta-data"
]
},
{
"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>0</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>next</th>\n",
" <td></td>\n",
" </tr>\n",
" <tr>\n",
" <th>method</th>\n",
" <td>Categories</td>\n",
" </tr>\n",
" <tr>\n",
" <th>total_count</th>\n",
" <td>33</td>\n",
" </tr>\n",
" <tr>\n",
" <th>link</th>\n",
" <td>https://api.meetup.com/2/categories</td>\n",
" </tr>\n",
" <tr>\n",
" <th>count</th>\n",
" <td>33</td>\n",
" </tr>\n",
" <tr>\n",
" <th>description</th>\n",
" <td>Returns a list of Meetup group categories</td>\n",
" </tr>\n",
" <tr>\n",
" <th>lon</th>\n",
" <td>None</td>\n",
" </tr>\n",
" <tr>\n",
" <th>title</th>\n",
" <td>Categories</td>\n",
" </tr>\n",
" <tr>\n",
" <th>url</th>\n",
" <td>https://api.meetup.com/2/categories?offset=0&amp;f...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>id</th>\n",
" <td></td>\n",
" </tr>\n",
" <tr>\n",
" <th>updated</th>\n",
" <td>1450292956000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>lat</th>\n",
" <td>None</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" 0\n",
"next \n",
"method Categories\n",
"total_count 33\n",
"link https://api.meetup.com/2/categories\n",
"count 33\n",
"description Returns a list of Meetup group categories\n",
"lon None\n",
"title Categories\n",
"url https://api.meetup.com/2/categories?offset=0&f...\n",
"id \n",
"updated 1450292956000\n",
"lat None"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cat_meta_df = parse_meta(categories)\n",
"cat_meta_df"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can see from the meta that there are 33 categories available to us.\n",
"I wonder what they are. \n",
"\n",
"Also, notice that the value of **next** (above) is an empty string. Meetup API v2 response payloads come in **pages**, one at a time, but provide the URI of the **next** API call in the sequence. We can use this to programmatically get each next **page** in **response.meta\\[\"next\"\\]**. until the complete result is returned.\n",
"\n",
"As we can see, the **response.meta\\[\"next\"\\]** for this page is an empty string, so all of the categories\n",
"fit into our first API call.\n",
"\n",
"#### Secondly, let's review the categories themselves"
]
},
{
"cell_type": "code",
"execution_count": 6,
"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>id</th>\n",
" <th>name</th>\n",
" <th>shortname</th>\n",
" <th>sort_name</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1</td>\n",
" <td>Arts &amp; Culture</td>\n",
" <td>Arts</td>\n",
" <td>Arts &amp; Culture</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>18</td>\n",
" <td>Book Clubs</td>\n",
" <td>Book Clubs</td>\n",
" <td>Book Clubs</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>2</td>\n",
" <td>Career &amp; Business</td>\n",
" <td>Business</td>\n",
" <td>Career &amp; Business</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>3</td>\n",
" <td>Cars &amp; Motorcycles</td>\n",
" <td>Auto</td>\n",
" <td>Cars &amp; Motorcycles</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>4</td>\n",
" <td>Community &amp; Environment</td>\n",
" <td>Community</td>\n",
" <td>Community &amp; Environment</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>5</td>\n",
" <td>Dancing</td>\n",
" <td>Dancing</td>\n",
" <td>Dancing</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>6</td>\n",
" <td>Education &amp; Learning</td>\n",
" <td>Education</td>\n",
" <td>Education &amp; Learning</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>8</td>\n",
" <td>Fashion &amp; Beauty</td>\n",
" <td>Fashion</td>\n",
" <td>Fashion &amp; Beauty</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>9</td>\n",
" <td>Fitness</td>\n",
" <td>Fitness</td>\n",
" <td>Fitness</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>10</td>\n",
" <td>Food &amp; Drink</td>\n",
" <td>Food &amp; Drink</td>\n",
" <td>Food &amp; Drink</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>11</td>\n",
" <td>Games</td>\n",
" <td>Games</td>\n",
" <td>Games</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>13</td>\n",
" <td>Movements &amp; Politics</td>\n",
" <td>Movements</td>\n",
" <td>Movements &amp; Politics</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>14</td>\n",
" <td>Health &amp; Wellbeing</td>\n",
" <td>Well-being</td>\n",
" <td>Health &amp; Wellbeing</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>15</td>\n",
" <td>Hobbies &amp; Crafts</td>\n",
" <td>Crafts</td>\n",
" <td>Hobbies &amp; Crafts</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>16</td>\n",
" <td>Language &amp; Ethnic Identity</td>\n",
" <td>Languages</td>\n",
" <td>Language &amp; Ethnic Identity</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>12</td>\n",
" <td>LGBT</td>\n",
" <td>LGBT</td>\n",
" <td>LGBT</td>\n",
" </tr>\n",
" <tr>\n",
" <th>16</th>\n",
" <td>17</td>\n",
" <td>Lifestyle</td>\n",
" <td>Lifestyle</td>\n",
" <td>Lifestyle</td>\n",
" </tr>\n",
" <tr>\n",
" <th>17</th>\n",
" <td>20</td>\n",
" <td>Movies &amp; Film</td>\n",
" <td>Films</td>\n",
" <td>Movies &amp; Film</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18</th>\n",
" <td>21</td>\n",
" <td>Music</td>\n",
" <td>Music</td>\n",
" <td>Music</td>\n",
" </tr>\n",
" <tr>\n",
" <th>19</th>\n",
" <td>22</td>\n",
" <td>New Age &amp; Spirituality</td>\n",
" <td>Spirituality</td>\n",
" <td>New Age &amp; Spirituality</td>\n",
" </tr>\n",
" <tr>\n",
" <th>20</th>\n",
" <td>23</td>\n",
" <td>Outdoors &amp; Adventure</td>\n",
" <td>Outdoors</td>\n",
" <td>Outdoors &amp; Adventure</td>\n",
" </tr>\n",
" <tr>\n",
" <th>21</th>\n",
" <td>24</td>\n",
" <td>Paranormal</td>\n",
" <td>Paranormal</td>\n",
" <td>Paranormal</td>\n",
" </tr>\n",
" <tr>\n",
" <th>22</th>\n",
" <td>25</td>\n",
" <td>Parents &amp; Family</td>\n",
" <td>Moms &amp; Dads</td>\n",
" <td>Parents &amp; Family</td>\n",
" </tr>\n",
" <tr>\n",
" <th>23</th>\n",
" <td>26</td>\n",
" <td>Pets &amp; Animals</td>\n",
" <td>Pets</td>\n",
" <td>Pets &amp; Animals</td>\n",
" </tr>\n",
" <tr>\n",
" <th>24</th>\n",
" <td>27</td>\n",
" <td>Photography</td>\n",
" <td>Photography</td>\n",
" <td>Photography</td>\n",
" </tr>\n",
" <tr>\n",
" <th>25</th>\n",
" <td>28</td>\n",
" <td>Religion &amp; Beliefs</td>\n",
" <td>Beliefs</td>\n",
" <td>Religion &amp; Beliefs</td>\n",
" </tr>\n",
" <tr>\n",
" <th>26</th>\n",
" <td>29</td>\n",
" <td>Sci-Fi &amp; Fantasy</td>\n",
" <td>Sci fi</td>\n",
" <td>Sci-Fi &amp; Fantasy</td>\n",
" </tr>\n",
" <tr>\n",
" <th>27</th>\n",
" <td>30</td>\n",
" <td>Singles</td>\n",
" <td>Singles</td>\n",
" <td>Singles</td>\n",
" </tr>\n",
" <tr>\n",
" <th>28</th>\n",
" <td>31</td>\n",
" <td>Socializing</td>\n",
" <td>Social</td>\n",
" <td>Socializing</td>\n",
" </tr>\n",
" <tr>\n",
" <th>29</th>\n",
" <td>32</td>\n",
" <td>Sports &amp; Recreation</td>\n",
" <td>Sports</td>\n",
" <td>Sports &amp; Recreation</td>\n",
" </tr>\n",
" <tr>\n",
" <th>30</th>\n",
" <td>33</td>\n",
" <td>Support</td>\n",
" <td>Support</td>\n",
" <td>Support</td>\n",
" </tr>\n",
" <tr>\n",
" <th>31</th>\n",
" <td>34</td>\n",
" <td>Tech</td>\n",
" <td>Tech</td>\n",
" <td>Tech</td>\n",
" </tr>\n",
" <tr>\n",
" <th>32</th>\n",
" <td>36</td>\n",
" <td>Writing</td>\n",
" <td>Writing</td>\n",
" <td>Writing</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" id name shortname sort_name\n",
"0 1 Arts & Culture Arts Arts & Culture\n",
"1 18 Book Clubs Book Clubs Book Clubs\n",
"2 2 Career & Business Business Career & Business\n",
"3 3 Cars & Motorcycles Auto Cars & Motorcycles\n",
"4 4 Community & Environment Community Community & Environment\n",
"5 5 Dancing Dancing Dancing\n",
"6 6 Education & Learning Education Education & Learning\n",
"7 8 Fashion & Beauty Fashion Fashion & Beauty\n",
"8 9 Fitness Fitness Fitness\n",
"9 10 Food & Drink Food & Drink Food & Drink\n",
"10 11 Games Games Games\n",
"11 13 Movements & Politics Movements Movements & Politics\n",
"12 14 Health & Wellbeing Well-being Health & Wellbeing\n",
"13 15 Hobbies & Crafts Crafts Hobbies & Crafts\n",
"14 16 Language & Ethnic Identity Languages Language & Ethnic Identity\n",
"15 12 LGBT LGBT LGBT\n",
"16 17 Lifestyle Lifestyle Lifestyle\n",
"17 20 Movies & Film Films Movies & Film\n",
"18 21 Music Music Music\n",
"19 22 New Age & Spirituality Spirituality New Age & Spirituality\n",
"20 23 Outdoors & Adventure Outdoors Outdoors & Adventure\n",
"21 24 Paranormal Paranormal Paranormal\n",
"22 25 Parents & Family Moms & Dads Parents & Family\n",
"23 26 Pets & Animals Pets Pets & Animals\n",
"24 27 Photography Photography Photography\n",
"25 28 Religion & Beliefs Beliefs Religion & Beliefs\n",
"26 29 Sci-Fi & Fantasy Sci fi Sci-Fi & Fantasy\n",
"27 30 Singles Singles Singles\n",
"28 31 Socializing Social Socializing\n",
"29 32 Sports & Recreation Sports Sports & Recreation\n",
"30 33 Support Support Support\n",
"31 34 Tech Tech Tech\n",
"32 36 Writing Writing Writing"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cats_df = parse_results(categories)\n",
"cats_df"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### So, if we want to work with a particular category\n",
"In this case, I want **Tech**. Let's query the dataframe for categories named **Tech**."
]
},
{
"cell_type": "code",
"execution_count": 7,
"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>id</th>\n",
" <th>name</th>\n",
" <th>shortname</th>\n",
" <th>sort_name</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>31</th>\n",
" <td>34</td>\n",
" <td>Tech</td>\n",
" <td>Tech</td>\n",
" <td>Tech</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" id name shortname sort_name\n",
"31 34 Tech Tech Tech"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tech_df = cats_df.loc[cats_df['name'] == 'Tech']\n",
"tech_df"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Let's store the category ID number for later use"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"34"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tech_category_id = tech_df['id'].values[0]\n",
"tech_category_id"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Explore Cities\n",
"### Now let's look at cities in the United States named San Francisco"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"%%capture --no-display\n",
"cities_resp = client.GetCities(country='United States', query='San Francisco')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here we used the [GetCities] method of the [Python Meetup API client]\n",
"\n",
"I used a query for cities in **United States** called **San Francisco**.\n",
"\n",
"[//]: # (References)\n",
"\n",
"[GetCities]: https://meetup-api.readthedocs.io/en/latest/meetup_api.html#meetup.api.meetup.api.Client.GetCities\n",
"[Python Meetup API client]: https://meetup-api.readthedocs.io/en/latest/meetup_api.html#api-client-details\n",
"\n",
"Now let's take a look at the **meta** for our results."
]
},
{
"cell_type": "code",
"execution_count": 10,
"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>0</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>next</th>\n",
" <td></td>\n",
" </tr>\n",
" <tr>\n",
" <th>method</th>\n",
" <td>Cities</td>\n",
" </tr>\n",
" <tr>\n",
" <th>total_count</th>\n",
" <td>10</td>\n",
" </tr>\n",
" <tr>\n",
" <th>link</th>\n",
" <td>https://api.meetup.com/2/cities</td>\n",
" </tr>\n",
" <tr>\n",
" <th>count</th>\n",
" <td>10</td>\n",
" </tr>\n",
" <tr>\n",
" <th>description</th>\n",
" <td>Returns Meetup cities. This method supports se...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>lon</th>\n",
" <td>None</td>\n",
" </tr>\n",
" <tr>\n",
" <th>title</th>\n",
" <td>Cities</td>\n",
" </tr>\n",
" <tr>\n",
" <th>url</th>\n",
" <td>https://api.meetup.com/2/cities?offset=0&amp;query...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>id</th>\n",
" <td></td>\n",
" </tr>\n",
" <tr>\n",
" <th>updated</th>\n",
" <td>1526855850000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>lat</th>\n",
" <td>None</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" 0\n",
"next \n",
"method Cities\n",
"total_count 10\n",
"link https://api.meetup.com/2/cities\n",
"count 10\n",
"description Returns Meetup cities. This method supports se...\n",
"lon None\n",
"title Cities\n",
"url https://api.meetup.com/2/cities?offset=0&query...\n",
"id \n",
"updated 1526855850000\n",
"lat None"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cities_meta_df = parse_meta(cities_resp)\n",
"cities_meta_df"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Hmm, a count of 10 cities is suspicious...\n",
"\n",
"I only know of the one San Francisco, why are there 10 cities?"
]
},
{
"cell_type": "code",
"execution_count": 11,
"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>city</th>\n",
" <th>country</th>\n",
" <th>id</th>\n",
" <th>lat</th>\n",
" <th>localized_country_name</th>\n",
" <th>lon</th>\n",
" <th>member_count</th>\n",
" <th>name_string</th>\n",
" <th>ranking</th>\n",
" <th>state</th>\n",
" <th>zip</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>San Francisco</td>\n",
" <td>us</td>\n",
" <td>94101</td>\n",
" <td>37.779999</td>\n",
" <td>USA</td>\n",
" <td>-122.419998</td>\n",
" <td>60351</td>\n",
" <td>San Francisco, California, USA</td>\n",
" <td>0</td>\n",
" <td>CA</td>\n",
" <td>94101</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Bosque</td>\n",
" <td>us</td>\n",
" <td>87006</td>\n",
" <td>34.560001</td>\n",
" <td>USA</td>\n",
" <td>-106.779999</td>\n",
" <td>5</td>\n",
" <td>San Francisco, New Mexico, USA</td>\n",
" <td>1</td>\n",
" <td>NM</td>\n",
" <td>87006</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>San Luis</td>\n",
" <td>us</td>\n",
" <td>81152</td>\n",
" <td>37.080002</td>\n",
" <td>USA</td>\n",
" <td>-105.620003</td>\n",
" <td>4</td>\n",
" <td>San Francisco, Colorado, USA</td>\n",
" <td>2</td>\n",
" <td>CO</td>\n",
" <td>81152</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>San Francisco de Macorís</td>\n",
" <td>do</td>\n",
" <td>1009671</td>\n",
" <td>19.299999</td>\n",
" <td>Dominican Republic</td>\n",
" <td>-70.250000</td>\n",
" <td>4</td>\n",
" <td>San Francisco de Macorís, Dominican Republic</td>\n",
" <td>3</td>\n",
" <td>NaN</td>\n",
" <td>meetup6</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>Reserve</td>\n",
" <td>us</td>\n",
" <td>87830</td>\n",
" <td>33.650002</td>\n",
" <td>USA</td>\n",
" <td>-108.769997</td>\n",
" <td>1</td>\n",
" <td>San Francisco Plaza, New Mexico, USA</td>\n",
" <td>4</td>\n",
" <td>NM</td>\n",
" <td>87830</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>San Francisco de Yojoa</td>\n",
" <td>hn</td>\n",
" <td>1016115</td>\n",
" <td>15.020000</td>\n",
" <td>Honduras</td>\n",
" <td>-87.970001</td>\n",
" <td>1</td>\n",
" <td>San Francisco de Yojoa, Honduras</td>\n",
" <td>5</td>\n",
" <td>NaN</td>\n",
" <td>meetup213</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>San Francisco del Mar</td>\n",
" <td>mx</td>\n",
" <td>1028671</td>\n",
" <td>16.230000</td>\n",
" <td>Mexico</td>\n",
" <td>-94.650002</td>\n",
" <td>1</td>\n",
" <td>San Francisco del Mar, Mexico</td>\n",
" <td>6</td>\n",
" <td>NaN</td>\n",
" <td>meetup1676</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>San Francisco Menéndez</td>\n",
" <td>sv</td>\n",
" <td>1038344</td>\n",
" <td>13.850000</td>\n",
" <td>El Salvador</td>\n",
" <td>-90.019997</td>\n",
" <td>0</td>\n",
" <td>San Francisco Menéndez, El Salvador</td>\n",
" <td>7</td>\n",
" <td>NaN</td>\n",
" <td>meetup110</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>San Francisco</td>\n",
" <td>ar</td>\n",
" <td>1111239</td>\n",
" <td>-31.430000</td>\n",
" <td>Argentina</td>\n",
" <td>-62.080002</td>\n",
" <td>0</td>\n",
" <td>San Francisco, Argentina</td>\n",
" <td>8</td>\n",
" <td>NaN</td>\n",
" <td>meetup95</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>San Francisco El Alto</td>\n",
" <td>gt</td>\n",
" <td>1015524</td>\n",
" <td>14.950000</td>\n",
" <td>Guatemala</td>\n",
" <td>-91.449997</td>\n",
" <td>0</td>\n",
" <td>San Francisco El Alto, Guatemala</td>\n",
" <td>9</td>\n",
" <td>NaN</td>\n",
" <td>meetup24</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" city country id lat \\\n",
"0 San Francisco us 94101 37.779999 \n",
"1 Bosque us 87006 34.560001 \n",
"2 San Luis us 81152 37.080002 \n",
"3 San Francisco de Macorís do 1009671 19.299999 \n",
"4 Reserve us 87830 33.650002 \n",
"5 San Francisco de Yojoa hn 1016115 15.020000 \n",
"6 San Francisco del Mar mx 1028671 16.230000 \n",
"7 San Francisco Menéndez sv 1038344 13.850000 \n",
"8 San Francisco ar 1111239 -31.430000 \n",
"9 San Francisco El Alto gt 1015524 14.950000 \n",
"\n",
" localized_country_name lon member_count \\\n",
"0 USA -122.419998 60351 \n",
"1 USA -106.779999 5 \n",
"2 USA -105.620003 4 \n",
"3 Dominican Republic -70.250000 4 \n",
"4 USA -108.769997 1 \n",
"5 Honduras -87.970001 1 \n",
"6 Mexico -94.650002 1 \n",
"7 El Salvador -90.019997 0 \n",
"8 Argentina -62.080002 0 \n",
"9 Guatemala -91.449997 0 \n",
"\n",
" name_string ranking state zip \n",
"0 San Francisco, California, USA 0 CA 94101 \n",
"1 San Francisco, New Mexico, USA 1 NM 87006 \n",
"2 San Francisco, Colorado, USA 2 CO 81152 \n",
"3 San Francisco de Macorís, Dominican Republic 3 NaN meetup6 \n",
"4 San Francisco Plaza, New Mexico, USA 4 NM 87830 \n",
"5 San Francisco de Yojoa, Honduras 5 NaN meetup213 \n",
"6 San Francisco del Mar, Mexico 6 NaN meetup1676 \n",
"7 San Francisco Menéndez, El Salvador 7 NaN meetup110 \n",
"8 San Francisco, Argentina 8 NaN meetup95 \n",
"9 San Francisco El Alto, Guatemala 9 NaN meetup24 "
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cities_df = parse_results(cities_resp)\n",
"cities_df"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Let's filter the dataframe with a query give us only cities in California, US"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead 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>city</th>\n",
" <th>country</th>\n",
" <th>id</th>\n",
" <th>lat</th>\n",
" <th>localized_country_name</th>\n",
" <th>lon</th>\n",
" <th>member_count</th>\n",
" <th>name_string</th>\n",
" <th>ranking</th>\n",
" <th>state</th>\n",
" <th>zip</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>San Francisco</td>\n",
" <td>us</td>\n",
" <td>94101</td>\n",
" <td>37.779999</td>\n",
" <td>USA</td>\n",
" <td>-122.419998</td>\n",
" <td>60351</td>\n",
" <td>San Francisco, California, USA</td>\n",
" <td>0</td>\n",
" <td>CA</td>\n",
" <td>94101</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" city country id lat localized_country_name lon \\\n",
"0 San Francisco us 94101 37.779999 USA -122.419998 \n",
"\n",
" member_count name_string ranking state zip \n",
"0 60351 San Francisco, California, USA 0 CA 94101 "
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"single_city_df = cities_df.loc[\n",
" (cities_df['state'] == 'CA') & \n",
" (cities_df['country'] == 'us')]\n",
"\n",
"single_city_df"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"One San Francisco, perfect! \n",
"\n",
"### Let's store the latitude and longitude for later use as well"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(37.779998779296875, -122.41999816894531)"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"latitude = single_city_df['lat'].values[0]\n",
"longitude = single_city_df['lon'].values[0]\n",
"latitude, longitude"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Now let's look at groups in San Francisco, CA"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Since we are going to grab lots of groups, lets make a function to help us call the API\n",
"\n",
"Note, this function will use the tech_category_id, latitude, and longitude values that we \n",
"found eariler."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"def get_a_group(page_number, category_id=tech_category_id, lat=latitude,\n",
" lon=longitude):\n",
" group = None\n",
" retry_counter, retry_max = 0, 3\n",
" print(f\"Getting page {page_number}\")\n",
" while retry_counter < retry_max:\n",
" try:\n",
" group = client.GetGroups(\n",
" category_id=category_id, lat=lat, lon=lon, offset=page_number)\n",
" return group\n",
" except:\n",
" print(f\"Fetch failure {retry_counter + 1}\")\n",
" retry_counter += 1\n",
"\n",
" raise Exception(f\"Unable to fetch page after {retry_counter} attempts\")\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Now, After grabbing the first group\n",
"\n",
"Let's review the **meta** to help us see what we are getting into"
]
},
{
"cell_type": "code",
"execution_count": 15,
"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>0</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>next</th>\n",
" <td>https://api.meetup.com/2/groups?offset=1&amp;forma...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>method</th>\n",
" <td>Groups</td>\n",
" </tr>\n",
" <tr>\n",
" <th>total_count</th>\n",
" <td>2186</td>\n",
" </tr>\n",
" <tr>\n",
" <th>link</th>\n",
" <td>https://api.meetup.com/2/groups</td>\n",
" </tr>\n",
" <tr>\n",
" <th>count</th>\n",
" <td>200</td>\n",
" </tr>\n",
" <tr>\n",
" <th>description</th>\n",
" <td>None</td>\n",
" </tr>\n",
" <tr>\n",
" <th>lon</th>\n",
" <td>-122.42</td>\n",
" </tr>\n",
" <tr>\n",
" <th>title</th>\n",
" <td>Meetup Groups v2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>url</th>\n",
" <td>https://api.meetup.com/2/groups?offset=0&amp;forma...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>id</th>\n",
" <td></td>\n",
" </tr>\n",
" <tr>\n",
" <th>updated</th>\n",
" <td>1550616065000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>lat</th>\n",
" <td>37.78</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" 0\n",
"next https://api.meetup.com/2/groups?offset=1&forma...\n",
"method Groups\n",
"total_count 2186\n",
"link https://api.meetup.com/2/groups\n",
"count 200\n",
"description None\n",
"lon -122.42\n",
"title Meetup Groups v2\n",
"url https://api.meetup.com/2/groups?offset=0&forma...\n",
"id \n",
"updated 1550616065000\n",
"lat 37.78"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%capture --no-display\n",
"group_resp = get_a_group(0)\n",
"group_meta = parse_meta(group_resp)\n",
"group_meta"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Wait! There's a meta[\\\"next\\\"].\n",
"\n",
"Remember earlier when I spoke about **response.meta\\[\"next\"\\]**? \n",
"\n",
"I seems as though our result will span mulitple API calls, each returning 200 new groups.\n",
"\n",
"Let's make a new helper that will grab each payload in a series of API calls until we obtain the entire data set:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"def get_all_groups_as_a_df():\n",
" \"\"\"Returns a single dataframe composed from data from multiple\n",
" successive calls to get_a_group.\n",
" \n",
" We will loop through get_a_group pages while our page.meta['next'] is \n",
" not the empty string.\n",
" \"\"\"\n",
" page_df_list = []\n",
" next_page = None\n",
" page_number = 0\n",
" while next_page != '': \n",
" page = get_a_group(page_number)\n",
" next_page = page.meta[\"next\"]\n",
" frame = parse_results(page)\n",
" page_number += 1\n",
" page_df_list.append(frame)\n",
" \n",
" return pd.concat(page_df_list, ignore_index=True)\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Getting page 0\n",
"28/30 (6 seconds remaining)\n",
"Getting page 1\n",
"27/30 (6 seconds remaining)\n",
"Getting page 2\n",
"26/30 (4 seconds remaining)\n",
"Getting page 3\n",
"25/30 (4 seconds remaining)\n",
"Getting page 4\n",
"24/30 (3 seconds remaining)\n",
"Getting page 5\n",
"23/30 (1 seconds remaining)\n",
"Getting page 6\n",
"22/30 (0 seconds remaining)\n",
"Getting page 7\n",
"29/30 (10 seconds remaining)\n",
"Getting page 8\n",
"28/30 (9 seconds remaining)\n",
"Getting page 9\n",
"27/30 (8 seconds remaining)\n",
"Getting page 10\n",
"26/30 (7 seconds remaining)\n"
]
},
{
"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>category</th>\n",
" <th>city</th>\n",
" <th>country</th>\n",
" <th>created</th>\n",
" <th>description</th>\n",
" <th>group_photo</th>\n",
" <th>id</th>\n",
" <th>join_mode</th>\n",
" <th>lat</th>\n",
" <th>link</th>\n",
" <th>...</th>\n",
" <th>name</th>\n",
" <th>organizer</th>\n",
" <th>rating</th>\n",
" <th>state</th>\n",
" <th>timezone</th>\n",
" <th>topics</th>\n",
" <th>urlname</th>\n",
" <th>utc_offset</th>\n",
" <th>visibility</th>\n",
" <th>who</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>{'name': 'tech', 'id': 34, 'shortname': 'tech'}</td>\n",
" <td>San Francisco</td>\n",
" <td>US</td>\n",
" <td>1034097740000</td>\n",
" <td>&lt;p&gt;The SF PHP Community Meetup is an open foru...</td>\n",
" <td>{'highres_link': 'https://secure.meetupstatic....</td>\n",
" <td>120903</td>\n",
" <td>open</td>\n",
" <td>37.77</td>\n",
" <td>https://www.meetup.com/sf-php/</td>\n",
" <td>...</td>\n",
" <td>SF PHP Community</td>\n",
" <td>{'member_id': 126468982, 'name': 'Andre Marigo...</td>\n",
" <td>4.38</td>\n",
" <td>CA</td>\n",
" <td>US/Pacific</td>\n",
" <td>[{'urlkey': 'php', 'name': 'PHP', 'id': 455}, ...</td>\n",
" <td>sf-php</td>\n",
" <td>-28800000</td>\n",
" <td>public</td>\n",
" <td>PHP Developers</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>1 rows × 22 columns</p>\n",
"</div>"
],
"text/plain": [
" category city country \\\n",
"0 {'name': 'tech', 'id': 34, 'shortname': 'tech'} San Francisco US \n",
"\n",
" created description \\\n",
"0 1034097740000 <p>The SF PHP Community Meetup is an open foru... \n",
"\n",
" group_photo id join_mode lat \\\n",
"0 {'highres_link': 'https://secure.meetupstatic.... 120903 open 37.77 \n",
"\n",
" link ... name \\\n",
"0 https://www.meetup.com/sf-php/ ... SF PHP Community \n",
"\n",
" organizer rating state timezone \\\n",
"0 {'member_id': 126468982, 'name': 'Andre Marigo... 4.38 CA US/Pacific \n",
"\n",
" topics urlname utc_offset \\\n",
"0 [{'urlkey': 'php', 'name': 'PHP', 'id': 455}, ... sf-php -28800000 \n",
"\n",
" visibility who \n",
"0 public PHP Developers \n",
"\n",
"[1 rows x 22 columns]"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Collect all groups into a single dataframe\n",
"all_groups_df = get_all_groups_as_a_df()\n",
"\n",
"# Show the first row in the dataframe\n",
"all_groups_df.head(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### That's too many columns\n",
"I really only care about a small list of columns, let's exclude the unneeded columns."
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead 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>id</th>\n",
" <th>name</th>\n",
" <th>members</th>\n",
" <th>rating</th>\n",
" <th>join_mode</th>\n",
" <th>urlname</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>120903</td>\n",
" <td>SF PHP Community</td>\n",
" <td>2696</td>\n",
" <td>4.38</td>\n",
" <td>open</td>\n",
" <td>sf-php</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" id name members rating join_mode urlname\n",
"0 120903 SF PHP Community 2696 4.38 open sf-php"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"column_list = ['id', 'name', 'members', 'rating', 'join_mode', 'urlname']\n",
"all_groups_df = all_groups_df[column_list]\n",
"all_groups_df.head(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Let's double check the size of our new dataframe"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(2186, 6)"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"all_groups_df.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"That looks just about right:\n",
"* 2186 rows\n",
"* 6 columns\n",
"\n",
"---\n",
"## Explore Members per Group\n",
"\n",
"Each group has a different sized membership, let's explore this first!\n",
"\n",
"\n",
"### Let's start with with a histogram\n",
"\n",
"This visualization should give us a basic idea of how big our groups are."
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 792x432 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# Using seaborn's distplot function\n",
"plt.rcParams['figure.figsize'] = [11, 6]\n",
"sb.distplot(all_groups_df['members'], kde=False, color=\"g\");"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### It appears that most groups are relatively small\n",
"\n",
"Let's take a closer look at some basic stats for our data in a tabular \n",
"format for some hard numbers:"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead 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>members</th>\n",
" <th>rating</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>count</th>\n",
" <td>2,186.00</td>\n",
" <td>2,186.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>mean</th>\n",
" <td>814.32</td>\n",
" <td>2.75</td>\n",
" </tr>\n",
" <tr>\n",
" <th>std</th>\n",
" <td>1,743.11</td>\n",
" <td>2.34</td>\n",
" </tr>\n",
" <tr>\n",
" <th>min</th>\n",
" <td>1.00</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>25%</th>\n",
" <td>87.25</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>50%</th>\n",
" <td>257.00</td>\n",
" <td>4.48</td>\n",
" </tr>\n",
" <tr>\n",
" <th>75%</th>\n",
" <td>781.75</td>\n",
" <td>4.84</td>\n",
" </tr>\n",
" <tr>\n",
" <th>max</th>\n",
" <td>36,050.00</td>\n",
" <td>5.00</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" members rating\n",
"count 2,186.00 2,186.00\n",
"mean 814.32 2.75\n",
"std 1,743.11 2.34\n",
"min 1.00 0.00\n",
"25% 87.25 0.00\n",
"50% 257.00 4.48\n",
"75% 781.75 4.84\n",
"max 36,050.00 5.00"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pd.options.display.float_format = '{:20,.2f}'.format\n",
"all_groups_df[[\"members\", \"rating\"]].describe()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As a table I can see some numbers:\n",
"\n",
"1. It looks like the average group size is about 814 persons.\n",
"2. Half of the group sits at or under 257 members.\n",
"3. The smallest group has a single person.\n",
"4. **the largest group has 36,000+ members!**\n",
"\n",
"What an outlier! But are there other **mega-groups** like this?\n",
"\n",
"### Maybe a box and whisker plot can visualize these stats for us"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYcAAARiCAYAAABPrzvoAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvOIA7rQAAIABJREFUeJzt3X+U3Xd93/nXW6NftjA1Mgq1LRmzjc9h3ElLklnDBm9PRQmxWQL0bOlGe7ZmowkUN5mlh25twvyROqlDzDklBR1Ij7PWxuzpDiWhJd6Cljpk9uTM5vBDbtwgrBJ7AxjZxj8icGwZSaPRZ//QlTriYyN5dK3rkR6Pc+bMnc98753PcJCfc7+f749qrQUAllo16gkA8OIjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHRWj3oCy/Xyl7+8XXnllaOeBsCKcs899zzRWtt0qu1WbByuvPLK7N69e9TTAFhRqupbp7Od3UoAdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQzI7O5uJiYmMjY1lYmIis7Ozo54SLNvqUU8AzgWzs7OZmZnJHXfckWuvvTbz8/OZmppKkmzbtm3Es4Pnr1pro57DskxOTrbdu3ePehqQJJmYmMiOHTuydevWE2Nzc3OZnp7Onj17RjgzOFlV3dNamzzlduIAZ25sbCwHDx7MmjVrTowtLCxk/fr1WVxcHOHM4GSnGwdrDjAE4+PjmZ+fP2lsfn4+4+PjI5oRnBlxgCGYmZnJ1NRU5ubmsrCwkLm5uUxNTWVmZmbUU4NlsSANQ3B80Xl6ejp79+7N+Ph4br31VovRrFjWHADOI9YcAFg2cQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYDOKeNQVeur6stV9Z+q6mtVdctg/Heq6htVde/g4zWD8aqqj1bVA1X1p1X1E0te651Vdf/g451Lxn+yqr46eM5Hq6peiF8WgNOz+jS2OZTkDa21p6tqTZL5qto1+N4/ba393g9sf32SqwYfr03yW0leW1Ubk/xKkskkLck9VXVXa+27g23eleRLST6X5LokuwLASJzynUM75unBl2sGH+2HPOVtST4xeN4Xk1xcVZcm+Zkkd7fW9g+CcHeS6wbfe2lr7YuttZbkE0nefga/EwBn6LTWHKpqrKruTfJYjv0H/kuDb9062HX0m1W1bjB2eZJvL3n6vsHYDxvf9yzjAIzIacWhtbbYWntNks1JrqmqiSS/nOTVSf7rJBuT3PyCzXKgqt5dVburavfjjz/+Qv84gPPW8zpaqbX2vSRzSa5rrT0y2HV0KMn/nuSawWYPJdmy5GmbB2M/bHzzs4w/28+/vbU22Vqb3LRp0/OZOgDPw+kcrbSpqi4ePL4gyU8n+c+DtYIMjix6e5I9g6fcleSGwVFLr0vyZGvtkSSfT/KmqnpZVb0syZuSfH7wvb+sqtcNXuuGJL8/3F8TgOfjdI5WujTJnVU1lmMx+VRr7d9X1R9W1aYkleTeJO8ZbP+5JG9O8kCSZ5L8fJK01vZX1a8l+cpgu19tre0fPP5HSX4nyQU5dpSSI5UARqiOHSC08kxOTrbdu3ePehoAK0pV3dNamzzVds6QBqAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAnVPGoarWV9WXq+o/VdXXquqWwfirqupLVfVAVf2bqlo7GF83+PqBwfevXPJavzwY/3pV/cyS8esGYw9U1fuH/2sC8HyczjuHQ0ne0Fr7m0lek+S6qnpdktuS/GZr7UeTfDfJ1GD7qSTfHYz/5mC7VNXVSX4uyV9Pcl2Sj1fVWFWNJflYkuuTXJ1k22BbAEbklHFoxzw9+HLN4KMleUOS3xuM35nk7YPHbxt8ncH3/05V1WD8k621Q621byR5IMk1g48HWmt/3lo7nOSTg20BGJHTWnMY/IV/b5LHktyd5P9L8r3W2pHBJvuSXD54fHmSbyfJ4PtPJrlk6fgPPOe5xgEYkdOKQ2ttsbX2miSbc+wv/Ve/oLN6DlX17qraXVW7H3/88VFMAeC88LyOVmqtfS/JXJL/JsnFVbV68K3NSR4aPH4oyZYkGXz/ryT5i6XjP/Cc5xp/tp9/e2ttsrU2uWnTpuczdQCeh9M5WmlTVV08eHxBkp9OsjfHIvH3Bpu9M8nvDx7fNfg6g+//YWutDcZ/bnA006uSXJXky0m+kuSqwdFPa3Ns0fquYfxyACzP6lNvkkuT3Dk4qmhVkk+11v59Vd2X5JNV9c+T/EmSOwbb35Hk/6iqB5Lsz7H/2Ke19rWq+lSS+5IcSfKLrbXFJKmqX0ry+SRjSXa21r42tN8QgOetjv1Rv/JMTk623bt3j3oaACtKVd3TWps81XbOkAagIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAJ1TxqGqtlTVXFXdV1Vfq6r3Dsb/WVU9VFX3Dj7evOQ5v1xVD1TV16vqZ5aMXzcYe6Cq3r9k/FVV9aXB+L+pqrXD/kUBOH2n887hSJJ/0lq7OsnrkvxiVV09+N5vttZeM/j4XJIMvvdzSf56kuuSfLyqxqpqLMnHklyf5Ook25a8zm2D1/rRJN9NMjWk3w+AZThlHFprj7TW/uPg8VNJ9ia5/Ic85W1JPtlaO9Ra+0aSB5JcM/h4oLX25621w0k+meRtVVVJ3pDk9wbPvzPJ25f7CwFw5p7XmkNVXZnkx5N8aTD0S1X1p1W1s6peNhi7PMm3lzxt32DsucYvSfK91tqRHxgHYEROOw5V9ZIkn07yj1trf5nkt5L8tSSvSfJIkn/xgszw5Dm8u6p2V9Xuxx9//IX+cQDnrdOKQ1WtybEw/OvW2r9Nktbao621xdba0SS/nWO7jZLkoSRbljx982Dsucb/IsnFVbX6B8Y7rbXbW2uTrbXJTZs2nc7UAViG0zlaqZLckWRva+3DS8YvXbLZ302yZ/D4riQ/V1XrqupVSa5K8uUkX0ly1eDIpLU5tmh9V2utJZlL8vcGz39nkt8/s18LgDOx+tSb5PVJ/kGSr1bVvYOxD+TY0UavSdKSfDPJP0yS1trXqupTSe7LsSOdfrG1tpgkVfVLST6fZCzJztba1wavd3OST1bVP0/yJzkWIwBGpI794b7yTE5Ott27d496GgArSlXd01qbPNV2zpAGoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwCdU8ahqrZU1VxV3VdVX6uq9w7GN1bV3VV1/+DzywbjVVUfraoHqupPq+onlrzWOwfb319V71wy/pNV9dXBcz5aVfVC/LIAnJ7TeedwJMk/aa1dneR1SX6xqq5O8v4kX2itXZXkC4Ovk+T6JFcNPt6d5LeSYzFJ8itJXpvkmiS/cjwog23eteR51535rwbAcp0yDq21R1pr/3Hw+Kkke5NcnuRtSe4cbHZnkrcPHr8tySfaMV9McnFVXZrkZ5Lc3Vrb31r7bpK7k1w3+N5LW2tfbK21JJ9Y8loAjMDzWnOoqiuT/HiSLyV5RWvtkcG3vpPkFYPHlyf59pKn7RuM/bDxfc8yDsCInHYcquolST6d5B+31v5y6fcGf/G3Ic/t2ebw7qraXVW7H3/88Rf6xwGct04rDlW1JsfC8K9ba/92MPzoYJdQBp8fG4w/lGTLkqdvHoz9sPHNzzLeaa3d3lqbbK1Nbtq06XSmDsAynM7RSpXkjiR7W2sfXvKtu5IcP+LonUl+f8n4DYOjll6X5MnB7qfPJ3lTVb1ssBD9piSfH3zvL6vqdYOfdcOS1wJgBFafxjavT/IPkny1qu4djH0gyW8k+VRVTSX5VpK/P/je55K8OckDSZ5J8vNJ0lrbX1W/luQrg+1+tbW2f/D4HyX5nSQXJNk1+ABgROrYcsHKMzk52Xbv3j3qaQCsKFV1T2tt8lTbOUMagI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGGZHZ2NhMTExkbG8vExERmZ2dHPSVYttWjngCcC2ZnZzMzM5M77rgj1157bebn5zM1NZUk2bZt24hnB89ftdZGPYdlmZycbLt37x71NCBJMjExkR07dmTr1q0nxubm5jI9PZ09e/aMcGZwsqq6p7U2ecrtxAHO3NjYWA4ePJg1a9acGFtYWMj69euzuLg4wpnByU43DtYcYAjGx8czPz9/0tj8/HzGx8dHNCM4M+IAQzAzM5OpqanMzc1lYWEhc3NzmZqayszMzKinBstiQRqG4Pii8/T0dPbu3Zvx8fHceuutFqNZsaw5AJxHrDkAsGziAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOMCSzs7OZmJjI2NhYJiYmMjs7O+opwbKtHvUE4FwwOzubmZmZ3HHHHbn22mszPz+fqampJMm2bdtGPDt4/qq1Nuo5LMvk5GTbvXv3qKcBSZKJiYns2LEjW7duPTE2NzeX6enp7NmzZ4Qzg5NV1T2ttclTbicOcObGxsZy8ODBrFmz5sTYwsJC1q9fn8XFxRHODE52unGw5gBDMD4+nvn5+ZPG5ufnMz4+PqIZwZkRBxiCmZmZTE1NZW5uLgsLC5mbm8vU1FRmZmZGPTVYFgvSMATHF52np6ezd+/ejI+P59Zbb7UYzYplzQHgPGLNAYBlEwcAOuIAQOeUcaiqnVX1WFXtWTL2z6rqoaq6d/Dx5iXf++WqeqCqvl5VP7Nk/LrB2ANV9f4l46+qqi8Nxv9NVa0d5i8IwPN3Ou8cfifJdc8y/puttdcMPj6XJFV1dZKfS/LXB8/5eFWNVdVYko8luT7J1Um2DbZNktsGr/WjSb6bZOpMfiEAztwp49Ba+6Mk+0/z9d6W5JOttUOttW8keSDJNYOPB1prf95aO5zkk0neVlWV5A1Jfm/w/DuTvP15/g4ADNmZrDn8UlX96WC308sGY5cn+faSbfYNxp5r/JIk32utHfmBcQBGaLlx+K0kfy3Ja5I8kuRfDG1GP0RVvbuqdlfV7scff/xs/EiA89Ky4tBae7S1tthaO5rkt3Nst1GSPJRky5JNNw/Gnmv8L5JcXFWrf2D8uX7u7a21ydba5KZNm5YzdXjBuJ8D55JlxaGqLl3y5d9NcvxIpruS/FxVrauqVyW5KsmXk3wlyVWDI5PW5tii9V3t2OnZc0n+3uD570zy+8uZE4zS8fs57NixIwcPHsyOHTsyMzMjEKxYp7x8RlXNJvnbSV6e5NEkvzL4+jVJWpJvJvmHrbVHBtvPJNme5EiSf9xa2zUYf3OSf5lkLMnO1tqtg/H/KscWqDcm+ZMk/1Nr7dCpJu7yGbyYuJ8DK4X7OcBZ5H4OrBSurQRnkfs5cK4RBxgC93PgXON+DjAE7ufAucaaA8B5xJoDAMsmDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOAHTEAYCOOADQEQcAOuIAQEccAOiIAwAdcQCgIw4AdMQBgI44ANARBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOMCSzs7OZmJjI2NhYJiYmMjs7O+opwbKtHvUE4FwwOzubmZmZ3HHHHbn22mszPz+fqampJMm2bdtGPDt4/qq1Nuo5LMvk5GTbvXv3qKcBSZKJiYns2LEjW7duPTE2NzeX6enp7NmzZ4Qzg5NV1T2ttclTbicOcObGxsZy8ODBrFmz5sTYwsJC1q9fn8XFxRHODE52unGw5gBDMD4+nvn5+ZPG5ufnMz4+PqIZwZkRBxiCmZmZTE1NZW5uLgsLC5mbm8vU1FRmZmZGPTVYFgvSMATHF52np6ezd+/ejI+P59Zbb7UYzYplzQHgPGLNAc4y5zlwLrFbCYbAeQ6ca+xWgiFwngMrhfMc4CxyngMrhTUHOIuc58C5RhxgCJznwLnGgjQMgfMcONdYcwA4j1hzAGDZxAGAjjgA0BEHADriAEBHHADoiAMAHXEAoCMOMCTu58C5xOUzYAjcz4FzjctnwBC4nwMrhctnwFm0d+/e7Nu376TdSvv27cvevXtHPTVYFnGAIbjssssyPT2dAwcOJEkOHDiQ6enpXHbZZSOeGSyPOMAQPPPMM3n66aczPT2dp556KtPT03n66afzzDPPjHpqsCziAEOwf//+3HTTTdm5c2cuuuii7Ny5MzfddFP2798/6qnBsogDDMnWrVuzZ8+eLC4uZs+ePSctTsNKIw4wBJs3b84NN9xw0m1Cb7jhhmzevHnUU4NlEQcYgg996ENZXFzM9u3bs27dumzfvj2Li4v50Ic+NOqpwbKIAwzBtm3b8pGPfCQbNmxIVWXDhg35yEc+4gQ4ViwnwQGcR5wEB8CyiQMAHXEAoCMOAHTEAYCOOMCQuNkP5xI3+4EhcLMfzjXOc4AhcLMfVorTPc9BHGAIxsbGcvDgwaxZs+bE2MLCQtavX5/FxcURzgxO5iQ4OIvGx8dzyy23nLTmcMstt2R8fHzUU4NlEQcYgq1bt+a2227L9u3b89RTT2X79u257bbbXLabFUscYAjm5uZy8803n3Szn5tvvjlzc3OjnhosizUHGAJrDqwU1hzgLBofH8/8/PxJY/Pz89YcWLHEAYZgZmYmU1NTJ90JbmpqKjMzM6OeGiyLk+BgCLZt25Y//uM/zvXXX59Dhw5l3bp1ede73uUEOFYs7xxgCGZnZ/PZz342u3btyuHDh7Nr16589rOfdQkNViwL0jAEzpBmpXCGNJxFjlZipXC0EpxFjlbiXCMOMASOVuJc42glGILjRyVNT09n7969GR8fz6233upoJVYsaw4A5xFrDgAsmzjAkLhNKOcSaw4wBG4TyrnGmgMMgZPgWCmcBAdnkZPgWCksSMNZ5CQ4zjXiAEPgJDjONRakYQicBMe5xpoDwHnEmgOcZc5z4FxitxIMgfMcONfYrQRD4DwHVgrnOcBZ5DwHVgprDnAWOc+Bc404wBA4z4FzjQVpGALnOXCuseYAcB6x5gDAsokDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMMiZv9cC5xbSUYAjf74Vzj2kowBG72w0rhZj9wFrnZDyuFC+/BWeRmP5xrxAGGwM1+ONecMg5VtbOqHquqPUvGNlbV3VV1/+DzywbjVVUfraoHqupPq+onljznnYPt76+qdy4Z/8mq+urgOR+tqhr2LwkvtG3btuXWW2/N9PR01q9fn+npaTf7YUU75ZpDVf2tJE8n+URrbWIw9qEk+1trv1FV70/ystbazVX15iTTSd6c5LVJPtJae21VbUyyO8lkkpbkniQ/2Vr7blV9Ocn/kuRLST6X5KOttV2nmrg1B4Dnb2hrDq21P0qy/weG35bkzsHjO5O8fcn4J9oxX0xycVVdmuRnktzdWtvfWvtukruTXDf43ktba19sxyr1iSWvBcCILHfN4RWttUcGj7+T5BWDx5cn+faS7fYNxn7Y+L5nGQdghM54QXrwF/9ZOR62qt5dVburavfjjz9+Nn4kwHlpuXF4dLBLKIPPjw3GH0qyZcl2mwdjP2x887OMP6vW2u2ttcnW2uSmTZuWOXUATmW5cbgryfEjjt6Z5PeXjN8wOGrpdUmeHOx++nySN1XVywZHNr0pyecH3/vLqnrd4CilG5a8FgAjcsprK1XVbJK/neTlVbUvya8k+Y0kn6qqqSTfSvL3B5t/LseOVHogyTNJfj5JWmv7q+rXknxlsN2vttaOL3L/oyS/k+SCJLsGHwCMkMtnAJxHXD4DgGUTBwA64gBARxwA6IgDAB1xAKAjDgB0xAGAjjgA0BEHADriAEBHHADoiAMMyezsbCYmJjI2NpaJiYnMzs6OekqwbOIAQzA7O5v3vve9OXDgQFprOXDgQN773vcKBCuWOMAQ3HTTTTl8+HCS5Nh9q5LDhw/npptuGuW0YNnEAYZg3759ueCCC7Jz584cPHgwO3fuzAUXXJB9+/aNemqwLOIAQ/K+970vW7duzZo1a7J169a8733vG/WUYNnEAYbkwx/+cObm5rKwsJC5ubl8+MMfHvWUYNlOeQ9p4NQ2b96cp556Ktu3b8+DDz6YK664It///vezefPmUU8NlsU7BxiCD33oQ1m7dm2S5Ph92deuXZsPfehDo5wWLJs4wBBs27YtH/nIR7Jhw4ZUVTZs2JCPfOQj2bZt26inBstSx//KWWkmJyfb7t27Rz0NgBWlqu5prU2eajvvHADoiAMAHXEAoCMOAHTEAYCOOMCQuGQ35xJnSMMQzM7OZmZmJnfccUeuvfbazM/PZ2pqKkmc68CK5DwHGIKJiYns2LEjW7duPTE2NzeX6enp7NmzZ4Qzg5Od7nkO4gBDMDY2loMHD2bNmjUnxhYWFrJ+/fosLi6OcGZwMifBwVk0Pj6e+fn5k8bm5+czPj4+ohnBmREHGIKZmZlMTU2ddMnuqampzMzMjHpqsCwWpGEIji86T09PZ+/evRkfH8+tt95qMZoVy5oDwHnEmgMAyyYOAHTEAYCOOMCQTE9PZ/369amqrF+/PtPT06OeEiybOMAQTE9P52Mf+9iJE94WFxfzsY99TCBYscQBhuDjH/94qiq33XZbDhw4kNtuuy1VlY9//OOjnhosi/McYAiOHj2aD37wg3nf+96XJHnf+96Xw4cP55d/+ZdHPDNYHu8cAOh45wBDMDY2lg984ANZu3Zt3vOWEKGLAAAUn0lEQVSe9+Rf/at/lQ984AMZGxsb9dRgWbxzgCG48cYbkyQ33XRTNmzYkJtuuumkcVhpvHOAIdixY0eS5Ld/+7ezuLiY1atX513veteJcVhpXFsJ4Dzi2koALJs4wJDMzs5mYmIiY2NjmZiYyOzs7KinBMtmzQGGYHZ2NjMzM7njjjty7bXXZn5+PlNTU0ning6sSNYcYAgmJiayY8eObN269cTY3Nxcpqens2fPnhHODE52umsO4gBDMDY2loMHD2bNmjUnxhYWFrJ+/foT11uCFwML0nAWjY+P55ZbbjlpzeGWW27J+Pj4qKcGyyIOMARbt27Nbbfdlu3bt+epp57K9u3bc9ttt520mwlWEruVYAgmJiZy1VVXZdeuXTl06FDWrVuX66+/Pvfff781B15U7FaCs+i+++7Lvffem127duXw4cPZtWtX7r333tx3332jnhosi0NZYQjWrl2b17/+9Zmens7evXszPj6e17/+9XnkkUdGPTVYFnGAITh06FBmZ2ezadOmtNbyxBNPZHZ2NkePHh311GBZ7FaCIVi9enUuuOCCXHDBBamqE49Xr/b3FyuTOMAQHDlyJBdddFF27tyZgwcPZufOnbnoooty5MiRUU8NlkUcYEiuueaaXH/99Vm7dm2uv/76XHPNNaOeEiybOMAQbNy4MZ/97Gfz67/+6zlw4EB+/dd/PZ/97GezcePGUU8NlkUcYAguvPDCvOQlL8mOHTtO+nzhhReOemqwLOIAQ/Dwww9nx44d2bBhQ6oqGzZsyI4dO/Lwww+PemqwLA6lgCEYHx/P5s2bTzobem5uzrWVWLG8c4AhmJmZydTUVObm5rKwsJC5ublMTU1lZmZm1FODZfHOAYbg+A19lp4hfeutt7rRDyuWC+8BnEdceA+AZRMHADriAEBHHADoiAMAHXGAIZmdnc3ExETGxsYyMTGR2dnZUU8Jls15DjAEs7OzmZmZyR133JFrr7028/PzmZqaShLnOrAiOc8BhmBiYiI7duzI1q1bT4zNzc1lenr6pEtqwKg5zwHOor179+Z3f/d3s379+lRV1q9fn9/93d/N3r17Rz01WBZxgCG4+OKLc/vtt590P4fbb789F1988ainBstitxIMwZo1a7Ju3bps2rQpDz74YK644oo8/vjjOXToUBYWFkY9PTjBbiU4i44cOZILLrggSXL8D64LLrjAPaRZscQBhqCq8o53vCPf+MY3cvTo0XzjG9/IO97xjlTVqKcGy2K3EgxBVaWqsmrVqiwuLmZsbCxHjx5Nay0r9d8Y5ya7leAs2rhxY1prWVxcTJIsLi6mtZaNGzeOeGawPOIAQ/Dkk08mScbGxk76fHwcVhpxgCE4/o5h06ZNWbVqVTZt2nTSOKw04gBD8pa3vCWPPPJIFhcX88gjj+Qtb3nLqKcEyyYOMCS7du3Khz/84TzzzDP58Ic/nF27do16SrBsjlaCIVizZs2JI5QWFhayZs2aE0cuOQmOFxNHK8FZ9J73vCcLCwu55JJLsmrVqlxyySVZWFjIe97znlFPDZZFHGAIduzYkTe+8Y159NFHc/To0Tz66KN54xvfmB07dox6arAs4gBDMDs7m/vvvz9f+MIXcvjw4XzhC1/I/fff74Y/rFjWHGAI3M+BleJ01xzEAYZgbGwsBw8ezJo1a06MLSwsZP369c514EXFgjScRePj47nllltOuof0LbfckvHx8VFPDZZFHGAItm7dmttuuy3bt2/PU089le3bt+e22247aTcTrCR2K8EQTExM5KqrrsquXbty6NChrFu3Ltdff33uv/9+aw68qJzubqXVZ2MycK6777778uijj+bSSy/Ngw8+mEsvvTTz8/P5i7/4i1FPDZbFbiUYgrGxsXz/+98/aez73//+iauzwkrjnQMMwZEjR3LkyJEcOHAgSfLNb35ztBOCM+SdAwzRy172spM+w0olDjAk69aty6c//ekcPnw4n/70p7Nu3bpRTwmWzW4lGJJ169Zl+/bt+da3vpVXvvKVWbduXQ4dOjTqacGyiAMMyfe///089NBDaa3loYceGvV0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\n",
"text/plain": [
"<Figure size 432x1440 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plt.rcParams['figure.figsize'] = [6, 20]\n",
"\n",
"#sb.set(style=\"whitegrid\")\n",
"#ax = sb.boxplot(y=\"members\", data=all_groups_df, palette=\"Set2\")\n",
"all_groups_df['members'].plot.box();"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Wow, there are quite a few **mega-groups**, as indicated by the circles above our top whisker!\n",
"\n",
"---\n",
"\n",
"Why are the groups so big?\n",
"\n",
"In fact...\n",
"\n",
"### What are the 10 biggest tech groups in the area?"
]
},
{
"cell_type": "code",
"execution_count": 23,
"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>id</th>\n",
" <th>name</th>\n",
" <th>members</th>\n",
" <th>rating</th>\n",
" <th>join_mode</th>\n",
" <th>urlname</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>19</th>\n",
" <td>844726</td>\n",
" <td>Silicon Valley Entrepreneurs &amp; Startups</td>\n",
" <td>36050</td>\n",
" <td>4.58</td>\n",
" <td>open</td>\n",
" <td>sventrepreneurs</td>\n",
" </tr>\n",
" <tr>\n",
" <th>107</th>\n",
" <td>1619955</td>\n",
" <td>SFHTML5</td>\n",
" <td>17656</td>\n",
" <td>4.67</td>\n",
" <td>open</td>\n",
" <td>sfhtml5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>106</th>\n",
" <td>1615633</td>\n",
" <td>Designers + Geeks</td>\n",
" <td>15433</td>\n",
" <td>4.46</td>\n",
" <td>open</td>\n",
" <td>designersgeeks</td>\n",
" </tr>\n",
" <tr>\n",
" <th>426</th>\n",
" <td>9226282</td>\n",
" <td>SF Data Science</td>\n",
" <td>14864</td>\n",
" <td>4.49</td>\n",
" <td>open</td>\n",
" <td>SF-Data-Science</td>\n",
" </tr>\n",
" <tr>\n",
" <th>28</th>\n",
" <td>1060260</td>\n",
" <td>The SF JavaScript Meetup</td>\n",
" <td>13354</td>\n",
" <td>4.54</td>\n",
" <td>open</td>\n",
" <td>jsmeetup</td>\n",
" </tr>\n",
" <tr>\n",
" <th>250</th>\n",
" <td>3483762</td>\n",
" <td>Tech in Motion Events: San Francisco</td>\n",
" <td>13073</td>\n",
" <td>4.48</td>\n",
" <td>approval</td>\n",
" <td>TechinMotionSF</td>\n",
" </tr>\n",
" <tr>\n",
" <th>540</th>\n",
" <td>13402242</td>\n",
" <td>Docker Online Meetup</td>\n",
" <td>12471</td>\n",
" <td>4.37</td>\n",
" <td>open</td>\n",
" <td>Docker-Online-Meetup</td>\n",
" </tr>\n",
" <tr>\n",
" <th>191</th>\n",
" <td>2065031</td>\n",
" <td>SF Data Mining</td>\n",
" <td>12378</td>\n",
" <td>4.64</td>\n",
" <td>open</td>\n",
" <td>Data-Mining</td>\n",
" </tr>\n",
" <tr>\n",
" <th>201</th>\n",
" <td>2252591</td>\n",
" <td>Women Who Code SF</td>\n",
" <td>12326</td>\n",
" <td>4.78</td>\n",
" <td>open</td>\n",
" <td>Women-Who-Code-SF</td>\n",
" </tr>\n",
" <tr>\n",
" <th>705</th>\n",
" <td>18354966</td>\n",
" <td>SF Big Analytics</td>\n",
" <td>11858</td>\n",
" <td>4.53</td>\n",
" <td>open</td>\n",
" <td>SF-Big-Analytics</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" id name members \\\n",
"19 844726 Silicon Valley Entrepreneurs & Startups 36050 \n",
"107 1619955 SFHTML5 17656 \n",
"106 1615633 Designers + Geeks 15433 \n",
"426 9226282 SF Data Science 14864 \n",
"28 1060260 The SF JavaScript Meetup 13354 \n",
"250 3483762 Tech in Motion Events: San Francisco 13073 \n",
"540 13402242 Docker Online Meetup 12471 \n",
"191 2065031 SF Data Mining 12378 \n",
"201 2252591 Women Who Code SF 12326 \n",
"705 18354966 SF Big Analytics 11858 \n",
"\n",
" rating join_mode urlname \n",
"19 4.58 open sventrepreneurs \n",
"107 4.67 open sfhtml5 \n",
"106 4.46 open designersgeeks \n",
"426 4.49 open SF-Data-Science \n",
"28 4.54 open jsmeetup \n",
"250 4.48 approval TechinMotionSF \n",
"540 4.37 open Docker-Online-Meetup \n",
"191 4.64 open Data-Mining \n",
"201 4.78 open Women-Who-Code-SF \n",
"705 4.53 open SF-Big-Analytics "
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"biggest_ten_df = all_groups_df.sort_values('members', ascending=False).head(10)\n",
"biggest_ten_df"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Get Group Events"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### We need to do some data shaping before the next api call\n",
"\n",
"Mostly we need to:\n",
"1. pass in a string with group ids from our 10 biggest groups\n",
"2. convert our human-readable date ranges to milliseconds since Jan 1, 1970\n",
"3. Call the GetEvents API filtering for past events using our group IDs and our date range\n",
"\n",
"#### First, let's make that string of group ids\n"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'844726,1619955,1615633,9226282,1060260,3483762,13402242,2065031,2252591,18354966'"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"id_list = biggest_ten_df['id'].tolist()\n",
"id_list\n",
"ids = ','.join(str(x) for x in id_list)\n",
"ids"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Now, let's get the epoch milliseconds for a date range between now and 9 months ago"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Now: 1550587334649, nine months ago: 1535035334649\n"
]
}
],
"source": [
"def to_millis(dt):\n",
" return int(pd.to_datetime(dt).value / 1000000)\n",
"\n",
"right_now = to_millis(datetime.datetime.now())\n",
"nine_months_ago = int(right_now - 180 * 24 * 60 * 60 * 1000)\n",
"print(f\"Now: {right_now}, nine months ago: {nine_months_ago}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Finally, let's look at those events."
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
"%%capture --no-display\n",
"events_resp = client.GetEvents(group_id=ids, status='past',\n",
" time=f\"{nine_months_ago},{right_now}\");"
]
},
{
"cell_type": "code",
"execution_count": 27,
"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>0</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>next</th>\n",
" <td></td>\n",
" </tr>\n",
" <tr>\n",
" <th>method</th>\n",
" <td>Events</td>\n",
" </tr>\n",
" <tr>\n",
" <th>total_count</th>\n",
" <td>106</td>\n",
" </tr>\n",
" <tr>\n",
" <th>link</th>\n",
" <td>https://api.meetup.com/2/events</td>\n",
" </tr>\n",
" <tr>\n",
" <th>count</th>\n",
" <td>106</td>\n",
" </tr>\n",
" <tr>\n",
" <th>description</th>\n",
" <td>Access Meetup events using a group, member, or...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>lon</th>\n",
" <td></td>\n",
" </tr>\n",
" <tr>\n",
" <th>title</th>\n",
" <td>Meetup Events v2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>url</th>\n",
" <td>https://api.meetup.com/2/events?offset=0&amp;forma...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>id</th>\n",
" <td></td>\n",
" </tr>\n",
" <tr>\n",
" <th>updated</th>\n",
" <td>1550349112000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>lat</th>\n",
" <td></td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" 0\n",
"next \n",
"method Events\n",
"total_count 106\n",
"link https://api.meetup.com/2/events\n",
"count 106\n",
"description Access Meetup events using a group, member, or...\n",
"lon \n",
"title Meetup Events v2\n",
"url https://api.meetup.com/2/events?offset=0&forma...\n",
"id \n",
"updated 1550349112000\n",
"lat "
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"parse_meta(events_resp)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Again, our raw results dataframe has extra columns that I don't care about"
]
},
{
"cell_type": "code",
"execution_count": 28,
"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>created</th>\n",
" <th>description</th>\n",
" <th>duration</th>\n",
" <th>event_url</th>\n",
" <th>group</th>\n",
" <th>headcount</th>\n",
" <th>how_to_find_us</th>\n",
" <th>id</th>\n",
" <th>maybe_rsvp_count</th>\n",
" <th>name</th>\n",
" <th>...</th>\n",
" <th>rating</th>\n",
" <th>rsvp_limit</th>\n",
" <th>status</th>\n",
" <th>time</th>\n",
" <th>updated</th>\n",
" <th>utc_offset</th>\n",
" <th>venue</th>\n",
" <th>visibility</th>\n",
" <th>waitlist_count</th>\n",
" <th>yes_rsvp_count</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1531451567000</td>\n",
" <td>&lt;p&gt;We are going to have two talks, one from Go...</td>\n",
" <td>10800000</td>\n",
" <td>https://www.meetup.com/SF-Big-Analytics/events...</td>\n",
" <td>{'join_mode': 'open', 'created': 1421705588000...</td>\n",
" <td>0</td>\n",
" <td>NaN</td>\n",
" <td>252731150</td>\n",
" <td>0</td>\n",
" <td>TensorFlow Probability and how Yelp use ML to ...</td>\n",
" <td>...</td>\n",
" <td>{'count': 0, 'average': 0}</td>\n",
" <td>nan</td>\n",
" <td>past</td>\n",
" <td>1535072400000</td>\n",
" <td>1535085901000</td>\n",
" <td>-25200000</td>\n",
" <td>{'zip': '94105', 'country': 'us', 'localized_c...</td>\n",
" <td>public</td>\n",
" <td>0</td>\n",
" <td>646</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>1 rows × 21 columns</p>\n",
"</div>"
],
"text/plain": [
" created description duration \\\n",
"0 1531451567000 <p>We are going to have two talks, one from Go... 10800000 \n",
"\n",
" event_url \\\n",
"0 https://www.meetup.com/SF-Big-Analytics/events... \n",
"\n",
" group headcount \\\n",
"0 {'join_mode': 'open', 'created': 1421705588000... 0 \n",
"\n",
" how_to_find_us id maybe_rsvp_count \\\n",
"0 NaN 252731150 0 \n",
"\n",
" name ... \\\n",
"0 TensorFlow Probability and how Yelp use ML to ... ... \n",
"\n",
" rating rsvp_limit status time \\\n",
"0 {'count': 0, 'average': 0} nan past 1535072400000 \n",
"\n",
" updated utc_offset \\\n",
"0 1535085901000 -25200000 \n",
"\n",
" venue visibility \\\n",
"0 {'zip': '94105', 'country': 'us', 'localized_c... public \n",
"\n",
" waitlist_count yes_rsvp_count \n",
"0 0 646 \n",
"\n",
"[1 rows x 21 columns]"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"raw_results_df = parse_results(events_resp)\n",
"raw_results_df.head(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### So again, let's filter down to just what's relevant"
]
},
{
"cell_type": "code",
"execution_count": 29,
"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>group</th>\n",
" <th>time</th>\n",
" <th>duration</th>\n",
" <th>yes_rsvp_count</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>{'join_mode': 'open', 'created': 1421705588000...</td>\n",
" <td>1535072400000</td>\n",
" <td>10800000</td>\n",
" <td>646</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" group time duration \\\n",
"0 {'join_mode': 'open', 'created': 1421705588000... 1535072400000 10800000 \n",
"\n",
" yes_rsvp_count \n",
"0 646 "
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"raw_results_df = parse_results(events_resp)\n",
"column_list = ['group', 'time', 'duration', 'yes_rsvp_count']\n",
"raw_results_df = raw_results_df[column_list]\n",
"raw_results_df.head(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### The group column\n",
"\n",
"The **group** column is actually a JSON object full of metadata about the group.\n",
"\n",
"I really only need the **group\\[\"id\"\\]** for now, so let's focus on that."
]
},
{
"cell_type": "code",
"execution_count": 30,
"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>id</th>\n",
" <th>time</th>\n",
" <th>duration</th>\n",
" <th>yes_rsvp_count</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>18354966</td>\n",
" <td>1535072400000</td>\n",
" <td>10800000</td>\n",
" <td>646</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" id time duration yes_rsvp_count\n",
"0 18354966 1535072400000 10800000 646"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def get_id(my_dict):\n",
" \"\"\"Extract the id member of a python dictionary\"\"\"\n",
" return my_dict[\"id\"]\n",
"\n",
"raw_results_df[\"id\"] = raw_results_df[\"group\"].apply(get_id)\n",
"\n",
"# Let's \n",
"columns = ['id', 'time', 'duration', 'yes_rsvp_count']\n",
"raw_results_df = raw_results_df[columns]\n",
"raw_results_df.head(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Hmm, it seems that our **time** is numeric\n",
"\n",
"The **time** is stored in **Epoch milliseconds** format.\n",
"\n",
"This is great if you want to see time as the number of milliseconds since Jan 1, 1970.\n",
"\n",
"This is not-so-great if you just want to see a human-readable date and time equivalent.\n",
"\n",
"Let's make a new human-readable column called **time_dt**"
]
},
{
"cell_type": "code",
"execution_count": 31,
"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>id</th>\n",
" <th>time</th>\n",
" <th>time_dt</th>\n",
" <th>duration</th>\n",
" <th>yes_rsvp_count</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>18354966</td>\n",
" <td>1535072400000</td>\n",
" <td>08/24/18 01:00</td>\n",
" <td>10800000</td>\n",
" <td>646</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" id time time_dt duration yes_rsvp_count\n",
"0 18354966 1535072400000 08/24/18 01:00 10800000 646"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"for field in [\"time\"]:\n",
" raw_results_df[\"time_dt\"] = pd.to_datetime(\n",
" raw_results_df[field], unit='ms').dt.strftime('%m/%d/%y %H:%M')\n",
" \n",
"columns = ['id', 'time','time_dt', 'duration', 'yes_rsvp_count']\n",
"raw_results_df = raw_results_df[columns]\n",
"raw_results_df.head(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Now let's convert the duration column to something human-readable\n",
"\n",
"Let's convert the column to a string that shows hours and minutes."
]
},
{
"cell_type": "code",
"execution_count": 32,
"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>id</th>\n",
" <th>time</th>\n",
" <th>time_dt</th>\n",
" <th>duration</th>\n",
" <th>yes_rsvp_count</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>18354966</td>\n",
" <td>1535072400000</td>\n",
" <td>08/24/18 01:00</td>\n",
" <td>3 hours, 0 minutes</td>\n",
" <td>646</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" id time time_dt duration yes_rsvp_count\n",
"0 18354966 1535072400000 08/24/18 01:00 3 hours, 0 minutes 646"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def millis_2_hours_and_minutes(ms):\n",
" \"\"\"Converts milliseconds to hours and minutes.\"\"\"\n",
" seconds = ms / 1000\n",
" minutes, seconds = divmod(seconds, 60)\n",
" hours, minutes = divmod(minutes, 60)\n",
"\n",
" return f\"{int(hours)} hours, {int(minutes)} minutes\" \n",
"\n",
"raw_results_df[\"duration\"] = raw_results_df[\"duration\"].apply(\n",
" millis_2_hours_and_minutes)\n",
"\n",
"raw_results_df.head(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Now let's join our top ten mega-groups dataframe with our events dataframe\n",
"\n",
"If you are familiar with SQL this is similar to a left join from **raw_results_df**\n",
"to **biggest_ten_df** on **id**\n",
"\n",
"Then we sort the output by **name** ascending and then **time** descending."
]
},
{
"cell_type": "code",
"execution_count": 33,
"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>name</th>\n",
" <th>time</th>\n",
" <th>time_dt</th>\n",
" <th>duration</th>\n",
" <th>yes_rsvp_count</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>60</th>\n",
" <td>Designers + Geeks</td>\n",
" <td>1542337200000</td>\n",
" <td>11/16/18 03:00</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>71</td>\n",
" </tr>\n",
" <tr>\n",
" <th>51</th>\n",
" <td>Designers + Geeks</td>\n",
" <td>1541124000000</td>\n",
" <td>11/02/18 02:00</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>71</td>\n",
" </tr>\n",
" <tr>\n",
" <th>37</th>\n",
" <td>Designers + Geeks</td>\n",
" <td>1539914400000</td>\n",
" <td>10/19/18 02:00</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>41</td>\n",
" </tr>\n",
" <tr>\n",
" <th>29</th>\n",
" <td>Designers + Geeks</td>\n",
" <td>1538704800000</td>\n",
" <td>10/05/18 02:00</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>29</td>\n",
" </tr>\n",
" <tr>\n",
" <th>19</th>\n",
" <td>Designers + Geeks</td>\n",
" <td>1537495200000</td>\n",
" <td>09/21/18 02:00</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>37</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>Designers + Geeks</td>\n",
" <td>1536285600000</td>\n",
" <td>09/07/18 02:00</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>87</td>\n",
" </tr>\n",
" <tr>\n",
" <th>45</th>\n",
" <td>Docker Online Meetup</td>\n",
" <td>1540915200000</td>\n",
" <td>10/30/18 16:00</td>\n",
" <td>1 hours, 0 minutes</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>102</th>\n",
" <td>SF Big Analytics</td>\n",
" <td>1549591200000</td>\n",
" <td>02/08/19 02:00</td>\n",
" <td>2 hours, 30 minutes</td>\n",
" <td>418</td>\n",
" </tr>\n",
" <tr>\n",
" <th>85</th>\n",
" <td>SF Big Analytics</td>\n",
" <td>1547690400000</td>\n",
" <td>01/17/19 02:00</td>\n",
" <td>3 hours, 0 minutes</td>\n",
" <td>450</td>\n",
" </tr>\n",
" <tr>\n",
" <th>83</th>\n",
" <td>SF Big Analytics</td>\n",
" <td>1547604000000</td>\n",
" <td>01/16/19 02:00</td>\n",
" <td>3 hours, 0 minutes</td>\n",
" <td>5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>69</th>\n",
" <td>SF Big Analytics</td>\n",
" <td>1544061600000</td>\n",
" <td>12/06/18 02:00</td>\n",
" <td>3 hours, 0 minutes</td>\n",
" <td>7</td>\n",
" </tr>\n",
" <tr>\n",
" <th>58</th>\n",
" <td>SF Big Analytics</td>\n",
" <td>1542247200000</td>\n",
" <td>11/15/18 02:00</td>\n",
" <td>3 hours, 0 minutes</td>\n",
" <td>16</td>\n",
" </tr>\n",
" <tr>\n",
" <th>56</th>\n",
" <td>SF Big Analytics</td>\n",
" <td>1542160800000</td>\n",
" <td>11/14/18 02:00</td>\n",
" <td>2 hours, 30 minutes</td>\n",
" <td>478</td>\n",
" </tr>\n",
" <tr>\n",
" <th>55</th>\n",
" <td>SF Big Analytics</td>\n",
" <td>1541782800000</td>\n",
" <td>11/09/18 17:00</td>\n",
" <td>57 hours, 0 minutes</td>\n",
" <td>16</td>\n",
" </tr>\n",
" <tr>\n",
" <th>49</th>\n",
" <td>SF Big Analytics</td>\n",
" <td>1541120400000</td>\n",
" <td>11/02/18 01:00</td>\n",
" <td>3 hours, 0 minutes</td>\n",
" <td>152</td>\n",
" </tr>\n",
" <tr>\n",
" <th>34</th>\n",
" <td>SF Big Analytics</td>\n",
" <td>1539909000000</td>\n",
" <td>10/19/18 00:30</td>\n",
" <td>2 hours, 30 minutes</td>\n",
" <td>390</td>\n",
" </tr>\n",
" <tr>\n",
" <th>21</th>\n",
" <td>SF Big Analytics</td>\n",
" <td>1538010000000</td>\n",
" <td>09/27/18 01:00</td>\n",
" <td>2 hours, 45 minutes</td>\n",
" <td>245</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>SF Big Analytics</td>\n",
" <td>1536800400000</td>\n",
" <td>09/13/18 01:00</td>\n",
" <td>2 hours, 30 minutes</td>\n",
" <td>218</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>SF Big Analytics</td>\n",
" <td>1535072400000</td>\n",
" <td>08/24/18 01:00</td>\n",
" <td>3 hours, 0 minutes</td>\n",
" <td>646</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>SF Data Mining</td>\n",
" <td>1537200000000</td>\n",
" <td>09/17/18 16:00</td>\n",
" <td>104 hours, 0 minutes</td>\n",
" <td>6</td>\n",
" </tr>\n",
" <tr>\n",
" <th>98</th>\n",
" <td>SF Data Science</td>\n",
" <td>1548988200000</td>\n",
" <td>02/01/19 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>94</td>\n",
" </tr>\n",
" <tr>\n",
" <th>94</th>\n",
" <td>SF Data Science</td>\n",
" <td>1548383400000</td>\n",
" <td>01/25/19 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>48</td>\n",
" </tr>\n",
" <tr>\n",
" <th>87</th>\n",
" <td>SF Data Science</td>\n",
" <td>1547778600000</td>\n",
" <td>01/18/19 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>26</td>\n",
" </tr>\n",
" <tr>\n",
" <th>86</th>\n",
" <td>SF Data Science</td>\n",
" <td>1547692200000</td>\n",
" <td>01/17/19 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>59</td>\n",
" </tr>\n",
" <tr>\n",
" <th>65</th>\n",
" <td>SF Data Science</td>\n",
" <td>1543539600000</td>\n",
" <td>11/30/18 01:00</td>\n",
" <td>3 hours, 30 minutes</td>\n",
" <td>18</td>\n",
" </tr>\n",
" <tr>\n",
" <th>57</th>\n",
" <td>SF Data Science</td>\n",
" <td>1542211200000</td>\n",
" <td>11/14/18 16:00</td>\n",
" <td>10 hours, 0 minutes</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>43</th>\n",
" <td>SF Data Science</td>\n",
" <td>1540774800000</td>\n",
" <td>10/29/18 01:00</td>\n",
" <td>4 hours, 0 minutes</td>\n",
" <td>21</td>\n",
" </tr>\n",
" <tr>\n",
" <th>35</th>\n",
" <td>SF Data Science</td>\n",
" <td>1539910800000</td>\n",
" <td>10/19/18 01:00</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>95</td>\n",
" </tr>\n",
" <tr>\n",
" <th>31</th>\n",
" <td>SF Data Science</td>\n",
" <td>1539306000000</td>\n",
" <td>10/12/18 01:00</td>\n",
" <td>3 hours, 0 minutes</td>\n",
" <td>15</td>\n",
" </tr>\n",
" <tr>\n",
" <th>104</th>\n",
" <td>SFHTML5</td>\n",
" <td>1550075400000</td>\n",
" <td>02/13/19 16:30</td>\n",
" <td>12 hours, 30 minutes</td>\n",
" <td>39</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>97</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1548815400000</td>\n",
" <td>01/30/19 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>37</td>\n",
" </tr>\n",
" <tr>\n",
" <th>91</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1548210600000</td>\n",
" <td>01/23/19 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>29</td>\n",
" </tr>\n",
" <tr>\n",
" <th>84</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1547605800000</td>\n",
" <td>01/16/19 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>32</td>\n",
" </tr>\n",
" <tr>\n",
" <th>81</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1547001000000</td>\n",
" <td>01/09/19 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>57</td>\n",
" </tr>\n",
" <tr>\n",
" <th>76</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1545271200000</td>\n",
" <td>12/20/18 02:00</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>199</td>\n",
" </tr>\n",
" <tr>\n",
" <th>74</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1545186600000</td>\n",
" <td>12/19/18 02:30</td>\n",
" <td>1 hours, 30 minutes</td>\n",
" <td>50</td>\n",
" </tr>\n",
" <tr>\n",
" <th>75</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1545186600000</td>\n",
" <td>12/19/18 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>23</td>\n",
" </tr>\n",
" <tr>\n",
" <th>72</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1544581800000</td>\n",
" <td>12/12/18 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>22</td>\n",
" </tr>\n",
" <tr>\n",
" <th>70</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1544149800000</td>\n",
" <td>12/07/18 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>17</td>\n",
" </tr>\n",
" <tr>\n",
" <th>68</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1543977000000</td>\n",
" <td>12/05/18 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>29</td>\n",
" </tr>\n",
" <tr>\n",
" <th>67</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1543975200000</td>\n",
" <td>12/05/18 02:00</td>\n",
" <td>3 hours, 0 minutes</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>63</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1542767400000</td>\n",
" <td>11/21/18 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>31</td>\n",
" </tr>\n",
" <tr>\n",
" <th>59</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1542335400000</td>\n",
" <td>11/16/18 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>50</td>\n",
" </tr>\n",
" <tr>\n",
" <th>54</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1541557800000</td>\n",
" <td>11/07/18 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>27</td>\n",
" </tr>\n",
" <tr>\n",
" <th>50</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1541122200000</td>\n",
" <td>11/02/18 01:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>50</td>\n",
" </tr>\n",
" <tr>\n",
" <th>48</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1540949400000</td>\n",
" <td>10/31/18 01:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>29</td>\n",
" </tr>\n",
" <tr>\n",
" <th>44</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1540859400000</td>\n",
" <td>10/30/18 00:30</td>\n",
" <td>2 hours, 30 minutes</td>\n",
" <td>64</td>\n",
" </tr>\n",
" <tr>\n",
" <th>39</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1540400400000</td>\n",
" <td>10/24/18 17:00</td>\n",
" <td>1 hours, 0 minutes</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>38</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1540344600000</td>\n",
" <td>10/24/18 01:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>36</td>\n",
" </tr>\n",
" <tr>\n",
" <th>36</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1539912600000</td>\n",
" <td>10/19/18 01:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>50</td>\n",
" </tr>\n",
" <tr>\n",
" <th>30</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1539135000000</td>\n",
" <td>10/10/18 01:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>25</td>\n",
" </tr>\n",
" <tr>\n",
" <th>28</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1538703000000</td>\n",
" <td>10/05/18 01:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>50</td>\n",
" </tr>\n",
" <tr>\n",
" <th>26</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1538530200000</td>\n",
" <td>10/03/18 01:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>10</td>\n",
" </tr>\n",
" <tr>\n",
" <th>27</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1538530200000</td>\n",
" <td>10/03/18 01:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>27</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1537493400000</td>\n",
" <td>09/21/18 01:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>33</td>\n",
" </tr>\n",
" <tr>\n",
" <th>16</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1537320600000</td>\n",
" <td>09/19/18 01:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>14</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1537030800000</td>\n",
" <td>09/15/18 17:00</td>\n",
" <td>3 hours, 0 minutes</td>\n",
" <td>10</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1536715800000</td>\n",
" <td>09/12/18 01:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>25</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1535506200000</td>\n",
" <td>08/29/18 01:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>35</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Women Who Code SF</td>\n",
" <td>1535074200000</td>\n",
" <td>08/24/18 01:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>50</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>106 rows × 5 columns</p>\n",
"</div>"
],
"text/plain": [
" name time time_dt \\\n",
"60 Designers + Geeks 1542337200000 11/16/18 03:00 \n",
"51 Designers + Geeks 1541124000000 11/02/18 02:00 \n",
"37 Designers + Geeks 1539914400000 10/19/18 02:00 \n",
"29 Designers + Geeks 1538704800000 10/05/18 02:00 \n",
"19 Designers + Geeks 1537495200000 09/21/18 02:00 \n",
"9 Designers + Geeks 1536285600000 09/07/18 02:00 \n",
"45 Docker Online Meetup 1540915200000 10/30/18 16:00 \n",
"102 SF Big Analytics 1549591200000 02/08/19 02:00 \n",
"85 SF Big Analytics 1547690400000 01/17/19 02:00 \n",
"83 SF Big Analytics 1547604000000 01/16/19 02:00 \n",
"69 SF Big Analytics 1544061600000 12/06/18 02:00 \n",
"58 SF Big Analytics 1542247200000 11/15/18 02:00 \n",
"56 SF Big Analytics 1542160800000 11/14/18 02:00 \n",
"55 SF Big Analytics 1541782800000 11/09/18 17:00 \n",
"49 SF Big Analytics 1541120400000 11/02/18 01:00 \n",
"34 SF Big Analytics 1539909000000 10/19/18 00:30 \n",
"21 SF Big Analytics 1538010000000 09/27/18 01:00 \n",
"13 SF Big Analytics 1536800400000 09/13/18 01:00 \n",
"0 SF Big Analytics 1535072400000 08/24/18 01:00 \n",
"15 SF Data Mining 1537200000000 09/17/18 16:00 \n",
"98 SF Data Science 1548988200000 02/01/19 02:30 \n",
"94 SF Data Science 1548383400000 01/25/19 02:30 \n",
"87 SF Data Science 1547778600000 01/18/19 02:30 \n",
"86 SF Data Science 1547692200000 01/17/19 02:30 \n",
"65 SF Data Science 1543539600000 11/30/18 01:00 \n",
"57 SF Data Science 1542211200000 11/14/18 16:00 \n",
"43 SF Data Science 1540774800000 10/29/18 01:00 \n",
"35 SF Data Science 1539910800000 10/19/18 01:00 \n",
"31 SF Data Science 1539306000000 10/12/18 01:00 \n",
"104 SFHTML5 1550075400000 02/13/19 16:30 \n",
".. ... ... ... \n",
"97 Women Who Code SF 1548815400000 01/30/19 02:30 \n",
"91 Women Who Code SF 1548210600000 01/23/19 02:30 \n",
"84 Women Who Code SF 1547605800000 01/16/19 02:30 \n",
"81 Women Who Code SF 1547001000000 01/09/19 02:30 \n",
"76 Women Who Code SF 1545271200000 12/20/18 02:00 \n",
"74 Women Who Code SF 1545186600000 12/19/18 02:30 \n",
"75 Women Who Code SF 1545186600000 12/19/18 02:30 \n",
"72 Women Who Code SF 1544581800000 12/12/18 02:30 \n",
"70 Women Who Code SF 1544149800000 12/07/18 02:30 \n",
"68 Women Who Code SF 1543977000000 12/05/18 02:30 \n",
"67 Women Who Code SF 1543975200000 12/05/18 02:00 \n",
"63 Women Who Code SF 1542767400000 11/21/18 02:30 \n",
"59 Women Who Code SF 1542335400000 11/16/18 02:30 \n",
"54 Women Who Code SF 1541557800000 11/07/18 02:30 \n",
"50 Women Who Code SF 1541122200000 11/02/18 01:30 \n",
"48 Women Who Code SF 1540949400000 10/31/18 01:30 \n",
"44 Women Who Code SF 1540859400000 10/30/18 00:30 \n",
"39 Women Who Code SF 1540400400000 10/24/18 17:00 \n",
"38 Women Who Code SF 1540344600000 10/24/18 01:30 \n",
"36 Women Who Code SF 1539912600000 10/19/18 01:30 \n",
"30 Women Who Code SF 1539135000000 10/10/18 01:30 \n",
"28 Women Who Code SF 1538703000000 10/05/18 01:30 \n",
"26 Women Who Code SF 1538530200000 10/03/18 01:30 \n",
"27 Women Who Code SF 1538530200000 10/03/18 01:30 \n",
"18 Women Who Code SF 1537493400000 09/21/18 01:30 \n",
"16 Women Who Code SF 1537320600000 09/19/18 01:30 \n",
"14 Women Who Code SF 1537030800000 09/15/18 17:00 \n",
"12 Women Who Code SF 1536715800000 09/12/18 01:30 \n",
"6 Women Who Code SF 1535506200000 08/29/18 01:30 \n",
"1 Women Who Code SF 1535074200000 08/24/18 01:30 \n",
"\n",
" duration yes_rsvp_count \n",
"60 2 hours, 0 minutes 71 \n",
"51 2 hours, 0 minutes 71 \n",
"37 2 hours, 0 minutes 41 \n",
"29 2 hours, 0 minutes 29 \n",
"19 2 hours, 0 minutes 37 \n",
"9 2 hours, 0 minutes 87 \n",
"45 1 hours, 0 minutes 1 \n",
"102 2 hours, 30 minutes 418 \n",
"85 3 hours, 0 minutes 450 \n",
"83 3 hours, 0 minutes 5 \n",
"69 3 hours, 0 minutes 7 \n",
"58 3 hours, 0 minutes 16 \n",
"56 2 hours, 30 minutes 478 \n",
"55 57 hours, 0 minutes 16 \n",
"49 3 hours, 0 minutes 152 \n",
"34 2 hours, 30 minutes 390 \n",
"21 2 hours, 45 minutes 245 \n",
"13 2 hours, 30 minutes 218 \n",
"0 3 hours, 0 minutes 646 \n",
"15 104 hours, 0 minutes 6 \n",
"98 2 hours, 0 minutes 94 \n",
"94 2 hours, 0 minutes 48 \n",
"87 2 hours, 0 minutes 26 \n",
"86 2 hours, 0 minutes 59 \n",
"65 3 hours, 30 minutes 18 \n",
"57 10 hours, 0 minutes 1 \n",
"43 4 hours, 0 minutes 21 \n",
"35 2 hours, 0 minutes 95 \n",
"31 3 hours, 0 minutes 15 \n",
"104 12 hours, 30 minutes 39 \n",
".. ... ... \n",
"97 2 hours, 0 minutes 37 \n",
"91 2 hours, 0 minutes 29 \n",
"84 2 hours, 0 minutes 32 \n",
"81 2 hours, 0 minutes 57 \n",
"76 2 hours, 0 minutes 199 \n",
"74 1 hours, 30 minutes 50 \n",
"75 2 hours, 0 minutes 23 \n",
"72 2 hours, 0 minutes 22 \n",
"70 2 hours, 0 minutes 17 \n",
"68 2 hours, 0 minutes 29 \n",
"67 3 hours, 0 minutes 1 \n",
"63 2 hours, 0 minutes 31 \n",
"59 2 hours, 0 minutes 50 \n",
"54 2 hours, 0 minutes 27 \n",
"50 2 hours, 0 minutes 50 \n",
"48 2 hours, 0 minutes 29 \n",
"44 2 hours, 30 minutes 64 \n",
"39 1 hours, 0 minutes 2 \n",
"38 2 hours, 0 minutes 36 \n",
"36 2 hours, 0 minutes 50 \n",
"30 2 hours, 0 minutes 25 \n",
"28 2 hours, 0 minutes 50 \n",
"26 2 hours, 0 minutes 10 \n",
"27 2 hours, 0 minutes 27 \n",
"18 2 hours, 0 minutes 33 \n",
"16 2 hours, 0 minutes 14 \n",
"14 3 hours, 0 minutes 10 \n",
"12 2 hours, 0 minutes 25 \n",
"6 2 hours, 0 minutes 35 \n",
"1 2 hours, 0 minutes 50 \n",
"\n",
"[106 rows x 5 columns]"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"merged_df = pd.merge(\n",
" raw_results_df,\n",
" biggest_ten_df[['id', 'name']],\n",
" on='id',\n",
" how='left')\n",
"\n",
"columns = ['name', 'time', 'time_dt', 'duration', 'yes_rsvp_count']\n",
"final_df = merged_df[columns]\n",
"\n",
"# Sort the output by name and time\n",
"final_df.sort_values(by=['name', 'time'], ascending=[True, False])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Ah, this is interesting\n",
"\n",
"From the top 10 mega-groups I can see that **SF Data Science** meets pretty regularly, and that their attendance is pretty consistent. \n",
"\n",
"Let's take a closer look at just this group by using another dataframe query."
]
},
{
"cell_type": "code",
"execution_count": 34,
"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>name</th>\n",
" <th>time</th>\n",
" <th>time_dt</th>\n",
" <th>duration</th>\n",
" <th>yes_rsvp_count</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>31</th>\n",
" <td>SF Data Science</td>\n",
" <td>1539306000000</td>\n",
" <td>10/12/18 01:00</td>\n",
" <td>3 hours, 0 minutes</td>\n",
" <td>15</td>\n",
" </tr>\n",
" <tr>\n",
" <th>35</th>\n",
" <td>SF Data Science</td>\n",
" <td>1539910800000</td>\n",
" <td>10/19/18 01:00</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>95</td>\n",
" </tr>\n",
" <tr>\n",
" <th>43</th>\n",
" <td>SF Data Science</td>\n",
" <td>1540774800000</td>\n",
" <td>10/29/18 01:00</td>\n",
" <td>4 hours, 0 minutes</td>\n",
" <td>21</td>\n",
" </tr>\n",
" <tr>\n",
" <th>57</th>\n",
" <td>SF Data Science</td>\n",
" <td>1542211200000</td>\n",
" <td>11/14/18 16:00</td>\n",
" <td>10 hours, 0 minutes</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>65</th>\n",
" <td>SF Data Science</td>\n",
" <td>1543539600000</td>\n",
" <td>11/30/18 01:00</td>\n",
" <td>3 hours, 30 minutes</td>\n",
" <td>18</td>\n",
" </tr>\n",
" <tr>\n",
" <th>86</th>\n",
" <td>SF Data Science</td>\n",
" <td>1547692200000</td>\n",
" <td>01/17/19 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>59</td>\n",
" </tr>\n",
" <tr>\n",
" <th>87</th>\n",
" <td>SF Data Science</td>\n",
" <td>1547778600000</td>\n",
" <td>01/18/19 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>26</td>\n",
" </tr>\n",
" <tr>\n",
" <th>94</th>\n",
" <td>SF Data Science</td>\n",
" <td>1548383400000</td>\n",
" <td>01/25/19 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>48</td>\n",
" </tr>\n",
" <tr>\n",
" <th>98</th>\n",
" <td>SF Data Science</td>\n",
" <td>1548988200000</td>\n",
" <td>02/01/19 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>94</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" name time time_dt duration \\\n",
"31 SF Data Science 1539306000000 10/12/18 01:00 3 hours, 0 minutes \n",
"35 SF Data Science 1539910800000 10/19/18 01:00 2 hours, 0 minutes \n",
"43 SF Data Science 1540774800000 10/29/18 01:00 4 hours, 0 minutes \n",
"57 SF Data Science 1542211200000 11/14/18 16:00 10 hours, 0 minutes \n",
"65 SF Data Science 1543539600000 11/30/18 01:00 3 hours, 30 minutes \n",
"86 SF Data Science 1547692200000 01/17/19 02:30 2 hours, 0 minutes \n",
"87 SF Data Science 1547778600000 01/18/19 02:30 2 hours, 0 minutes \n",
"94 SF Data Science 1548383400000 01/25/19 02:30 2 hours, 0 minutes \n",
"98 SF Data Science 1548988200000 02/01/19 02:30 2 hours, 0 minutes \n",
"\n",
" yes_rsvp_count \n",
"31 15 \n",
"35 95 \n",
"43 21 \n",
"57 1 \n",
"65 18 \n",
"86 59 \n",
"87 26 \n",
"94 48 \n",
"98 94 "
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"interesting_group_df = final_df[final_df['name'] == \"SF Data Science\"]\n",
"interesting_group_df"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### A simple bar chart shows us something\n",
"\n",
"I will use the **time_dt** column vs **yes_rsvp_count** to see if people\n",
"are looking forward to new events."
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAosAAAG6CAYAAABgJAyCAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvOIA7rQAAIABJREFUeJzt3Xu4XQV57/vvDxJAAYkEpAJqolzEAgJNaDnoEXTLxXjksr1gsYKgiIqKthasCtbWHtT9tEKfemFrEbWIRTfVDd4QwUu7uYQYLxCQCEFDhUYkgHpQQt7zx5yENdZcg4SwssbKnN/P86yHOceYc62XN++a+WVcU1VIkiRJE9mk6wIkSZI0fRkWJUmS1MqwKEmSpFaGRUmSJLUyLEqSJKmVYVGSJEmtDIuSJElqZViUJElSK8OiJEmSWs2Yyh+23Xbb1Zw5c6byR0qSJGkC11133S+ravu1vW5Kw+KcOXNYuHDhVP5ISZIkTSDJbevyOndDS5IkqZVhUZIkSa0Mi5IkSWo1pccsShp+DzzwAMuXL+f+++/vuhSthy222IKdd96ZmTNndl2KpGnCsChpUi1fvpytt96aOXPmkKTrcvQoVBV33XUXy5cvZ+7cuV2XI2macDe0pEl1//33M3v2bIPiRigJs2fPdquwpAbDoqRJZ1DcePlnJ2k8w6IkSZJaecyipA1qzumXTur3W3bWgkn9fqNo5cqVXHDBBbzxjW/suhRJGwG3LErSenjwwQe7LmG9rVy5ko985CNdlyFpI2FYlDR0zjjjDD784Q+vef6ud72Ls88+mw996EPMnz+fvffemzPPPBOA3/zmNyxYsIBnP/vZ7Lnnnnz+859v/b5z5szhtNNOY7/99uOiiy7inHPO4VnPehZ77703xxxzDKtXr2bOnDmsXLlyzXt23XVX7rzzTo4//nhOPvlk5s2bx2677cYll1zS+nMefPBB/uIv/oI999yTvffem3/8x38E4PLLL2ffffdlr7324oQTTuB3v/vdmrp++ctfArBw4UIOOuggAN773vdywgkncNBBB/H0pz+dc845B4DTTz+dn/70p+yzzz684x3vWI8OSxol7oaWNHROOOEEjj76aE499VRWr17NhRdeyN/93d9x+eWXc80111BVvOQlL+E73/kOK1asYMcdd+TSS3u7y++5555H/N6zZ89m0aJFAOy4447ceuutbL755qxcuZJNNtmEI444gosvvpjXvOY1XH311TztaU9jhx12AGDZsmVcc801/PSnP+Xggw9m6dKlbLHFFgM/49xzz2XZsmUsXryYGTNm8Ktf/Yr777+f448/nssvv5zddtuNV7/61Xz0ox/l1FNPfcR6b7zxRq644gruu+8+dt99d97whjdw1lln8eMf/5jFixevT3sljRi3LEoaOnPmzGH27Nl8//vf5xvf+Ab77rsv11577ZrH++23HzfeeCM333wze+21F5dddhmnnXYa3/3ud9lmm20e8Xu/4hWvWPN477335thjj+Wzn/0sM2bMWLP+oa2TF154YeP1L3/5y9lkk03YddddefrTn86NN9444c/45je/yetf//o133PbbbflpptuYu7cuey2224AHHfccXznO99Zay8WLFjA5ptvznbbbceTnvQk7rzzzrW+R5LGMixKGkqvfe1r+dSnPsV5553HCSecQFXxzne+k8WLF7N48WKWLl3KiSeeyG677caiRYvYa6+9ePe738373ve+R/y+W2655ZrHl156KW9605tYtGgR8+fPZ9WqVRxwwAEsXbqUFStW8G//9m8cffTRa14//rI0k3WZmhkzZrB69WqAgWskbr755mseb7rppqxatWpSfqak0eFu6I3cZJ9pur48Q1XTzVFHHcUZZ5zBAw88wAUXXMCMGTN4z3vew7HHHstWW23F7bffzsyZM1m1ahXbbrstr3rVq5g1axaf+MQn1un7r169mp///OccfPDBPOc5z+HCCy/k17/+NbNmzeKoo47i7W9/O3vssQezZ89e856LLrqI4447jltvvZVbbrmF3XfffcLv/cIXvpCPf/zjHHzwwWt2Q+++++4sW7aMpUuXsssuu/CZz3yG5z3veUBvS+p1113H4Ycfzhe/+MW11r711ltz3333rdP/pyQZFiVtUF39Q2KzzTbj4IMPZtasWWy66aYccsghLFmyhAMOOACArbbais9+9rMsXbqUd7zjHWyyySbMnDmTj370o+v0/R988EFe9apXcc8991BVvOUtb2HWrFlAb1f0/Pnz+dSnPtV4z1Of+lT2339/7r33Xj72sY9NeLwi9LaK/uQnP2Hvvfdm5syZvO51r+OUU07hvPPO42UvexmrVq1i/vz5nHzyyQCceeaZ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\n",
"text/plain": [
"<Figure size 792x432 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plt.rcParams['figure.figsize'] = [11, 6]\n",
"\n",
"lines = interesting_group_df[['yes_rsvp_count', 'time_dt']].plot(\n",
" kind='bar', x='time_dt', y='yes_rsvp_count', style='.-')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"This is nice, but what is the trend, is the group active? It's tough to tell\n",
"from a simple bar chart.\n",
"\n",
"### Let's visualize the trend line\n",
"\n",
"Let's see the trend using a seaborn regplot. \n",
"\n",
"I'll use the epoch milliseconds **time** column of our dataframe, since it is numeric and can be used to generate a trend line."
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.axes._subplots.AxesSubplot at 0x7fe27cd0cb38>"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 792x432 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"sb.regplot(x='time', y='yes_rsvp_count', data=interesting_group_df,\n",
" color=\"green\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Goal Achieved!\n",
"\n",
"At last! We found a Tech group in San Francisco, CA that:\n",
"1. is among the 10 biggest in the city\n",
"2. has a trend of more and more people RSVP-ing to their events\n",
"3. holds events occuring every few weeks.\n",
"\n",
"## Conclusion\n",
"\n",
"We achieved our objectives and demonstrated several useful techniques along the way we :\n",
"1. worked with the [Python Meetup API client]\n",
"2. built helper functions to deal with our response objects' **meta** and **results** dictionaries\n",
"3. loaded pages of **results** from multiple API calls into Pandas dataframes\n",
"4. Used pandas.DataFrame.[query] to sort and filter data of interest\n",
"5. Used pandas.DataFrame.[apply] to clean columns of data using custom helper functions\n",
"6. Used pandas.DataFrame.[describe] to get descriptive statistics that summarize\n",
" * the central tendency\n",
" * dispersion\n",
" * shape of our dataset's distribution\n",
"7. Used pandas.DataFrame.[merge] to join the **events** and **groups** dataframes to create a report of the events for our 10 biggest mega-groups in technology\n",
"8. Found a mega-group that shows enduring and increasing interest by its membership\n",
"\n",
"\n",
"[//]: # (References)\n",
"\n",
"[Python Meetup API client]: https://meetup-api.readthedocs.io/en/latest/meetup_api.html#api-client-details\n",
"[query]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.query.html\n",
"[apply]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.apply.html\n",
"[describe]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.describe.html\n",
"[merge]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.merge.html"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python (datascience_challenges)",
"language": "python",
"name": "datascience_challenges"
},
"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.7.2"
},
"toc": {
"base_numbering": 1,
"nav_menu": {},
"number_sections": false,
"sideBar": true,
"skip_h1_title": false,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": true,
"toc_position": {},
"toc_section_display": true,
"toc_window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment