Skip to content

Instantly share code, notes, and snippets.

@redpanda-ai
Created February 21, 2019 12:13
Show Gist options
  • Save redpanda-ai/45b7e7c2abceb8e04fcbc9c8f2302cf8 to your computer and use it in GitHub Desktop.
Save redpanda-ai/45b7e7c2abceb8e04fcbc9c8f2302cf8 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"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 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",
"## Okay, but what I really want to know is\n",
"\n",
"What is the biggest Tech Group in San Francisco that meets regularly and has a growing and enthusiastic membership?\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": [
"### What are the attributes of the response object? \n",
"\n",
"First, \n",
"let's create ahelper function to help us parse out the two most useful\n",
"different pieces:\n",
"\n",
"1. **meta**: an object containing meta-data about the response object itself\n",
"2. **results**: A page of actual data from the entire result of our API call"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"def parse_response(response):\n",
" \"\"\"Returns two dataframes, meta and results:\n",
" meta: a vertically aligned dataframe, where each row is an element \n",
" of the response.meta dictionary\n",
" results: a horizontally aligned dataframe, where each column is\n",
" an element of the response.results dictionary\"\"\"\n",
" meta = pd.DataFrame.from_dict(response.meta, orient='index')\n",
" results = pd.DataFrame.from_dict(response.results)\n",
" return meta, results\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Exploring the response object\n",
"\n",
"We received a response object when we called ```client.GetCategories()```.\n",
"\n",
"By looking at the categories **meta** dataframe, we can see that there are 33 different categories."
]
},
{
"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": [
"cats_meta_df, cats_df = parse_response(categories)\n",
"cats_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",
"### How the Meetup API works\n",
"\n",
"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 results dataframe"
]
},
{
"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"
]
},
{
"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": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"34"
]
},
"execution_count": 21,
"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": 22,
"metadata": {},
"outputs": [],
"source": [
"%%capture --no-display\n",
"cities_resp = client.GetCities(country='us', 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": 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>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>4</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>4</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?country=us&amp;off...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>id</th>\n",
" <td></td>\n",
" </tr>\n",
" <tr>\n",
" <th>updated</th>\n",
" <td>1263132740000</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 4\n",
"link https://api.meetup.com/2/cities\n",
"count 4\n",
"description Returns Meetup cities. This method supports se...\n",
"lon None\n",
"title Cities\n",
"url https://api.meetup.com/2/cities?country=us&off...\n",
"id \n",
"updated 1263132740000\n",
"lat None"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cities_meta_df, cities_df = parse_response(cities_resp)\n",
"cities_meta_df"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Hmm, a count of 4 cities is suspicious...\n",
"\n",
"I only know of the one San Francisco, why are there 4 cities?"
]
},
{
"cell_type": "code",
"execution_count": 24,
"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>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>3</td>\n",
" <td>NM</td>\n",
" <td>87830</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",
"1 Bosque us 87006 34.560001 USA -106.779999 \n",
"2 San Luis us 81152 37.080002 USA -105.620003 \n",
"3 Reserve us 87830 33.650002 USA -108.769997 \n",
"\n",
" member_count name_string ranking state zip \n",
"0 60351 San Francisco, California, USA 0 CA 94101 \n",
"1 5 San Francisco, New Mexico, USA 1 NM 87006 \n",
"2 4 San Francisco, Colorado, USA 2 CO 81152 \n",
"3 1 San Francisco Plaza, New Mexico, USA 3 NM 87830 "
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cities_df"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Oh, there are lot's of San Franciscos!\n",
"\n",
"### Let's filter the dataframe with a query to give us only cities in California, US"
]
},
{
"cell_type": "code",
"execution_count": 25,
"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": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"single_city_df = cities_df.loc[\n",
" (cities_df['state'] == 'CA')]\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": 28,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(37.779998779296875, -122.41999816894531)"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"latitude = single_city_df['lat'][0]\n",
"longitude = single_city_df['lon'][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": 29,
"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\")"
]
},
{
"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": 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>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>2189</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>1550723256000</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 2189\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 1550723256000\n",
"lat 37.78"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%capture --no-display\n",
"group_resp = get_a_group(0)\n",
"group_meta, _ = parse_response(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",
"It seems as though our result will span mulitple API calls, each returning 200 new groups in \n",
"a **page**.\n",
"\n",
"Let's make a new helper that will grab each **page** in a series of API calls until we obtain the entire data set:\n",
"\n",
"We will use the pandas.DataFrame.[concat] function to collate all pages into a single useful dataframe\n",
"\n",
"[//]: # (References)\n",
"\n",
"[concat]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.concat.html"
]
},
{
"cell_type": "code",
"execution_count": 31,
"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_response(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": 32,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Getting page 0\n",
"29/30 (10 seconds remaining)\n",
"Getting page 1\n",
"28/30 (9 seconds remaining)\n",
"Getting page 2\n",
"27/30 (8 seconds remaining)\n",
"Getting page 3\n",
"26/30 (7 seconds remaining)\n",
"Getting page 4\n",
"25/30 (5 seconds remaining)\n",
"Getting page 5\n",
"24/30 (4 seconds remaining)\n",
"Getting page 6\n",
"23/30 (4 seconds remaining)\n",
"Getting page 7\n",
"22/30 (3 seconds remaining)\n",
"Getting page 8\n",
"21/30 (2 seconds remaining)\n",
"Getting page 9\n",
"20/30 (1 seconds remaining)\n",
"Getting page 10\n",
"29/30 (10 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": 32,
"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>2699</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 2699 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": [
"(2189, 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",
"* 2189 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,189.00</td>\n",
" <td>2,189.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>mean</th>\n",
" <td>813.80</td>\n",
" <td>2.75</td>\n",
" </tr>\n",
" <tr>\n",
" <th>std</th>\n",
" <td>1,742.79</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.00</td>\n",
" <td>0.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>50%</th>\n",
" <td>257.00</td>\n",
" <td>4.47</td>\n",
" </tr>\n",
" <tr>\n",
" <th>75%</th>\n",
" <td>782.00</td>\n",
" <td>4.84</td>\n",
" </tr>\n",
" <tr>\n",
" <th>max</th>\n",
" <td>36,057.00</td>\n",
" <td>5.00</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" members rating\n",
"count 2,189.00 2,189.00\n",
"mean 813.80 2.75\n",
"std 1,742.79 2.34\n",
"min 1.00 0.00\n",
"25% 87.00 0.00\n",
"50% 257.00 4.47\n",
"75% 782.00 4.84\n",
"max 36,057.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": "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T09nz549x2JQVdmzZ0+mp6fHPDMYjjjACDzyyCNJctx5DivHYbURBxiBffv2Zd26dbnqqqtSVbnqqquybt267Nu3b9xTg6GIA4zI5ORktm3bloMHD2bbtm2OVmJVEwcYkUOHDr3g17CaOJQVRuSZZ57Jz/zMz2R5ebk7WxpWG+8cYATWr1/fHbZaVVm/fv2YZgSnRhxgBC644IK84hWvyBVXXJE1a9bkiiuuyCte8YpccMEF454aDEUcYAQeffTRbN26NevWrUuSrFu3Llu3bs2jjz465pnBcMQBRmBqairf+ta3jhv71re+5TahrFriACPgNqGcacQBRmBxcTG33HJLtm3blgsvvDDbtm3LLbfcksXFxXFPDYbiZj8wAhMTEzlw4MBxJ74tLS1l7dq1DmnlZcXNfuA0mpqayq233prp6elMTExkeno6t956qzUHVi1xgBHYtGlTPvKRj+Sb3/xmDh8+nG9+85v5yEc+Ys2BVUscYAR+67d+K0myYcOGrFmzJhs2bDhuHFYbcYAR2LdvX9797nfnkksuSZJccsklefe73+2qrKxa4gAjcs8992T//v1prWX//v255557xj0lGJo4wIg89dRTmZubyzPPPJO5ubk89dRT454SDM2hrDACVZWqyqte9ars3bs3l156aR5//PG01rJa/41xZnIoK5xmb3vb2/Lkk08mSZ588sm87W1vG/OMYHjiACOwcePGfPGLXzzuHtJf/OIXs3HjxjHPDIYjDjAC11xzTZ599tksLS0lOXJ29LPPPptrrrlmzDOD4YgDjMAXv/jFJEcuo7Hy89FxWG3EAUbg8OHDWbduXa644opUVa644oqsW7fu2G4mWG1OKQ5V9WdV9fWqur+qdg7G1lfVvVX14ODzxYPxqqpPVtVDVfXHVfWTK17nPYPtH6yq95zarwTjs23bthw8eDDbtm0b91TglJwzgtfY1Fr73oqvP5TkS621j1bVhwZf35LkhiRXDz5en+TXk7y+qtYn+eUkM0lakvuq6u7W2vdHMDc4bfbv35/Nmzfn8ccfz6te9ars379/3FOCob0Uu5XekeSuweO7krxzxfhn2hFfTnJRVb06yVuS3Nta2zcIwr1Jrn8J5gUvub1796a1lr179457KnBKTjUOLcl/qKr7qup9g7FLW2uPDR5/N8mlg8eXJ/nOiufuGYz9qHFY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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",
"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>36057</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>17671</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>15443</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>14868</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>13356</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>13078</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>12475</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>12331</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>11869</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 36057 \n",
"107 1619955 SFHTML5 17671 \n",
"106 1615633 Designers + Geeks 15443 \n",
"426 9226282 SF Data Science 14868 \n",
"28 1060260 The SF JavaScript Meetup 13356 \n",
"250 3483762 Tech in Motion Events: San Francisco 13078 \n",
"540 13402242 Docker Online Meetup 12475 \n",
"191 2065031 SF Data Mining 12378 \n",
"201 2252591 Women Who Code SF 12331 \n",
"705 18354966 SF Big Analytics 11869 \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: 1550687560221, nine months ago: 1535135560221\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}\");\n",
"\n",
"events_meta, events_df = parse_response(events_resp)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Again, our events_df dataframe has extra columns that I don't care about"
]
},
{
"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>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>1532649759000</td>\n",
" <td>&lt;p&gt;Join us for an evening of TensorFlow.js tal...</td>\n",
" <td>14400000</td>\n",
" <td>https://www.meetup.com/sfhtml5/events/253185437/</td>\n",
" <td>{'join_mode': 'open', 'created': 1269470260000...</td>\n",
" <td>0</td>\n",
" <td>Event will be on the 7th Floor</td>\n",
" <td>253185437</td>\n",
" <td>0</td>\n",
" <td>TensorFlow.js with Nick Kreeger and Ping Yu</td>\n",
" <td>...</td>\n",
" <td>{'count': 0, 'average': 0}</td>\n",
" <td>470.00</td>\n",
" <td>past</td>\n",
" <td>1535155200000</td>\n",
" <td>1535171121000</td>\n",
" <td>-25200000</td>\n",
" <td>{'zip': '94105', 'country': 'us', 'localized_c...</td>\n",
" <td>public</td>\n",
" <td>0</td>\n",
" <td>454</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>1 rows × 21 columns</p>\n",
"</div>"
],
"text/plain": [
" created description duration \\\n",
"0 1532649759000 <p>Join us for an evening of TensorFlow.js tal... 14400000 \n",
"\n",
" event_url \\\n",
"0 https://www.meetup.com/sfhtml5/events/253185437/ \n",
"\n",
" group headcount \\\n",
"0 {'join_mode': 'open', 'created': 1269470260000... 0 \n",
"\n",
" how_to_find_us id maybe_rsvp_count \\\n",
"0 Event will be on the 7th Floor 253185437 0 \n",
"\n",
" name ... \\\n",
"0 TensorFlow.js with Nick Kreeger and Ping Yu ... \n",
"\n",
" rating rsvp_limit status time \\\n",
"0 {'count': 0, 'average': 0} 470.00 past 1535155200000 \n",
"\n",
" updated utc_offset \\\n",
"0 1535171121000 -25200000 \n",
"\n",
" venue visibility \\\n",
"0 {'zip': '94105', 'country': 'us', 'localized_c... public \n",
"\n",
" waitlist_count yes_rsvp_count \n",
"0 0 454 \n",
"\n",
"[1 rows x 21 columns]"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"events_df.head(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### So again, let's filter down to just what's relevant"
]
},
{
"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>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': 1269470260000...</td>\n",
" <td>1535155200000</td>\n",
" <td>14400000</td>\n",
" <td>454</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" group time duration \\\n",
"0 {'join_mode': 'open', 'created': 1269470260000... 1535155200000 14400000 \n",
"\n",
" yes_rsvp_count \n",
"0 454 "
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"column_list = ['group', 'time', 'duration', 'yes_rsvp_count']\n",
"events_df = events_df[column_list]\n",
"events_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": 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>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>1619955</td>\n",
" <td>1535155200000</td>\n",
" <td>14400000</td>\n",
" <td>454</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" id time duration yes_rsvp_count\n",
"0 1619955 1535155200000 14400000 454"
]
},
"execution_count": 29,
"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",
"events_df[\"id\"] = events_df[\"group\"].apply(get_id)\n",
"\n",
"# Let's \n",
"columns = ['id', 'time', 'duration', 'yes_rsvp_count']\n",
"events_df = events_df[columns]\n",
"events_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": 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>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>1619955</td>\n",
" <td>1535155200000</td>\n",
" <td>08/25/18 00:00</td>\n",
" <td>14400000</td>\n",
" <td>454</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" id time time_dt duration yes_rsvp_count\n",
"0 1619955 1535155200000 08/25/18 00:00 14400000 454"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"events_df[\"time_dt\"] = pd.to_datetime(\n",
" events_df[\"time\"], unit='ms').dt.strftime('%m/%d/%y %H:%M')\n",
" \n",
"columns = ['id', 'time','time_dt', 'duration', 'yes_rsvp_count']\n",
"events_df = events_df[columns]\n",
"events_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": 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>1619955</td>\n",
" <td>1535155200000</td>\n",
" <td>08/25/18 00:00</td>\n",
" <td>4 hours, 0 minutes</td>\n",
" <td>454</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" id time time_dt duration yes_rsvp_count\n",
"0 1619955 1535155200000 08/25/18 00:00 4 hours, 0 minutes 454"
]
},
"execution_count": 31,
"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",
"events_df[\"duration\"] = events_df[\"duration\"].apply(\n",
" millis_2_hours_and_minutes)\n",
"\n",
"events_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": 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>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>57</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>48</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>34</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>26</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>16</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>6</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>42</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>99</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>82</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>80</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>66</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>55</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>53</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>52</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>46</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>31</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>18</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>10</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>12</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>95</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>91</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>84</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>83</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>62</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>54</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>40</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>32</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>28</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>101</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>92</th>\n",
" <td>SFHTML5</td>\n",
" <td>1548464400000</td>\n",
" <td>01/26/19 01:00</td>\n",
" <td>3 hours, 30 minutes</td>\n",
" <td>419</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>1549420200000</td>\n",
" <td>02/06/19 02:30</td>\n",
" <td>2 hours, 0 minutes</td>\n",
" <td>47</td>\n",
" </tr>\n",
" <tr>\n",
" <th>94</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>88</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>81</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>78</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>73</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>71</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>72</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>69</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>67</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>65</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>64</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>60</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>56</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>51</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>47</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>45</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>41</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>36</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>35</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>33</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>27</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>25</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>23</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>24</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>15</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>13</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>11</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>9</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>3</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",
" </tbody>\n",
"</table>\n",
"<p>103 rows × 5 columns</p>\n",
"</div>"
],
"text/plain": [
" name time time_dt \\\n",
"57 Designers + Geeks 1542337200000 11/16/18 03:00 \n",
"48 Designers + Geeks 1541124000000 11/02/18 02:00 \n",
"34 Designers + Geeks 1539914400000 10/19/18 02:00 \n",
"26 Designers + Geeks 1538704800000 10/05/18 02:00 \n",
"16 Designers + Geeks 1537495200000 09/21/18 02:00 \n",
"6 Designers + Geeks 1536285600000 09/07/18 02:00 \n",
"42 Docker Online Meetup 1540915200000 10/30/18 16:00 \n",
"99 SF Big Analytics 1549591200000 02/08/19 02:00 \n",
"82 SF Big Analytics 1547690400000 01/17/19 02:00 \n",
"80 SF Big Analytics 1547604000000 01/16/19 02:00 \n",
"66 SF Big Analytics 1544061600000 12/06/18 02:00 \n",
"55 SF Big Analytics 1542247200000 11/15/18 02:00 \n",
"53 SF Big Analytics 1542160800000 11/14/18 02:00 \n",
"52 SF Big Analytics 1541782800000 11/09/18 17:00 \n",
"46 SF Big Analytics 1541120400000 11/02/18 01:00 \n",
"31 SF Big Analytics 1539909000000 10/19/18 00:30 \n",
"18 SF Big Analytics 1538010000000 09/27/18 01:00 \n",
"10 SF Big Analytics 1536800400000 09/13/18 01:00 \n",
"12 SF Data Mining 1537200000000 09/17/18 16:00 \n",
"95 SF Data Science 1548988200000 02/01/19 02:30 \n",
"91 SF Data Science 1548383400000 01/25/19 02:30 \n",
"84 SF Data Science 1547778600000 01/18/19 02:30 \n",
"83 SF Data Science 1547692200000 01/17/19 02:30 \n",
"62 SF Data Science 1543539600000 11/30/18 01:00 \n",
"54 SF Data Science 1542211200000 11/14/18 16:00 \n",
"40 SF Data Science 1540774800000 10/29/18 01:00 \n",
"32 SF Data Science 1539910800000 10/19/18 01:00 \n",
"28 SF Data Science 1539306000000 10/12/18 01:00 \n",
"101 SFHTML5 1550075400000 02/13/19 16:30 \n",
"92 SFHTML5 1548464400000 01/26/19 01:00 \n",
".. ... ... ... \n",
"97 Women Who Code SF 1549420200000 02/06/19 02:30 \n",
"94 Women Who Code SF 1548815400000 01/30/19 02:30 \n",
"88 Women Who Code SF 1548210600000 01/23/19 02:30 \n",
"81 Women Who Code SF 1547605800000 01/16/19 02:30 \n",
"78 Women Who Code SF 1547001000000 01/09/19 02:30 \n",
"73 Women Who Code SF 1545271200000 12/20/18 02:00 \n",
"71 Women Who Code SF 1545186600000 12/19/18 02:30 \n",
"72 Women Who Code SF 1545186600000 12/19/18 02:30 \n",
"69 Women Who Code SF 1544581800000 12/12/18 02:30 \n",
"67 Women Who Code SF 1544149800000 12/07/18 02:30 \n",
"65 Women Who Code SF 1543977000000 12/05/18 02:30 \n",
"64 Women Who Code SF 1543975200000 12/05/18 02:00 \n",
"60 Women Who Code SF 1542767400000 11/21/18 02:30 \n",
"56 Women Who Code SF 1542335400000 11/16/18 02:30 \n",
"51 Women Who Code SF 1541557800000 11/07/18 02:30 \n",
"47 Women Who Code SF 1541122200000 11/02/18 01:30 \n",
"45 Women Who Code SF 1540949400000 10/31/18 01:30 \n",
"41 Women Who Code SF 1540859400000 10/30/18 00:30 \n",
"36 Women Who Code SF 1540400400000 10/24/18 17:00 \n",
"35 Women Who Code SF 1540344600000 10/24/18 01:30 \n",
"33 Women Who Code SF 1539912600000 10/19/18 01:30 \n",
"27 Women Who Code SF 1539135000000 10/10/18 01:30 \n",
"25 Women Who Code SF 1538703000000 10/05/18 01:30 \n",
"23 Women Who Code SF 1538530200000 10/03/18 01:30 \n",
"24 Women Who Code SF 1538530200000 10/03/18 01:30 \n",
"15 Women Who Code SF 1537493400000 09/21/18 01:30 \n",
"13 Women Who Code SF 1537320600000 09/19/18 01:30 \n",
"11 Women Who Code SF 1537030800000 09/15/18 17:00 \n",
"9 Women Who Code SF 1536715800000 09/12/18 01:30 \n",
"3 Women Who Code SF 1535506200000 08/29/18 01:30 \n",
"\n",
" duration yes_rsvp_count \n",
"57 2 hours, 0 minutes 71 \n",
"48 2 hours, 0 minutes 71 \n",
"34 2 hours, 0 minutes 41 \n",
"26 2 hours, 0 minutes 29 \n",
"16 2 hours, 0 minutes 37 \n",
"6 2 hours, 0 minutes 87 \n",
"42 1 hours, 0 minutes 1 \n",
"99 2 hours, 30 minutes 418 \n",
"82 3 hours, 0 minutes 450 \n",
"80 3 hours, 0 minutes 5 \n",
"66 3 hours, 0 minutes 7 \n",
"55 3 hours, 0 minutes 16 \n",
"53 2 hours, 30 minutes 478 \n",
"52 57 hours, 0 minutes 16 \n",
"46 3 hours, 0 minutes 152 \n",
"31 2 hours, 30 minutes 390 \n",
"18 2 hours, 45 minutes 245 \n",
"10 2 hours, 30 minutes 218 \n",
"12 104 hours, 0 minutes 6 \n",
"95 2 hours, 0 minutes 94 \n",
"91 2 hours, 0 minutes 48 \n",
"84 2 hours, 0 minutes 26 \n",
"83 2 hours, 0 minutes 59 \n",
"62 3 hours, 30 minutes 18 \n",
"54 10 hours, 0 minutes 1 \n",
"40 4 hours, 0 minutes 21 \n",
"32 2 hours, 0 minutes 95 \n",
"28 3 hours, 0 minutes 15 \n",
"101 12 hours, 30 minutes 39 \n",
"92 3 hours, 30 minutes 419 \n",
".. ... ... \n",
"97 2 hours, 0 minutes 47 \n",
"94 2 hours, 0 minutes 37 \n",
"88 2 hours, 0 minutes 29 \n",
"81 2 hours, 0 minutes 32 \n",
"78 2 hours, 0 minutes 57 \n",
"73 2 hours, 0 minutes 199 \n",
"71 1 hours, 30 minutes 50 \n",
"72 2 hours, 0 minutes 23 \n",
"69 2 hours, 0 minutes 22 \n",
"67 2 hours, 0 minutes 17 \n",
"65 2 hours, 0 minutes 29 \n",
"64 3 hours, 0 minutes 1 \n",
"60 2 hours, 0 minutes 31 \n",
"56 2 hours, 0 minutes 50 \n",
"51 2 hours, 0 minutes 27 \n",
"47 2 hours, 0 minutes 50 \n",
"45 2 hours, 0 minutes 29 \n",
"41 2 hours, 30 minutes 64 \n",
"36 1 hours, 0 minutes 2 \n",
"35 2 hours, 0 minutes 36 \n",
"33 2 hours, 0 minutes 50 \n",
"27 2 hours, 0 minutes 25 \n",
"25 2 hours, 0 minutes 50 \n",
"23 2 hours, 0 minutes 10 \n",
"24 2 hours, 0 minutes 27 \n",
"15 2 hours, 0 minutes 33 \n",
"13 2 hours, 0 minutes 14 \n",
"11 3 hours, 0 minutes 10 \n",
"9 2 hours, 0 minutes 25 \n",
"3 2 hours, 0 minutes 35 \n",
"\n",
"[103 rows x 5 columns]"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"merged_df = pd.merge(\n",
" events_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": 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>28</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>32</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>40</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>54</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>62</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>83</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>84</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>91</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>95</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",
"28 SF Data Science 1539306000000 10/12/18 01:00 3 hours, 0 minutes \n",
"32 SF Data Science 1539910800000 10/19/18 01:00 2 hours, 0 minutes \n",
"40 SF Data Science 1540774800000 10/29/18 01:00 4 hours, 0 minutes \n",
"54 SF Data Science 1542211200000 11/14/18 16:00 10 hours, 0 minutes \n",
"62 SF Data Science 1543539600000 11/30/18 01:00 3 hours, 30 minutes \n",
"83 SF Data Science 1547692200000 01/17/19 02:30 2 hours, 0 minutes \n",
"84 SF Data Science 1547778600000 01/18/19 02:30 2 hours, 0 minutes \n",
"91 SF Data Science 1548383400000 01/25/19 02:30 2 hours, 0 minutes \n",
"95 SF Data Science 1548988200000 02/01/19 02:30 2 hours, 0 minutes \n",
"\n",
" yes_rsvp_count \n",
"28 15 \n",
"32 95 \n",
"40 21 \n",
"54 1 \n",
"62 18 \n",
"83 59 \n",
"84 26 \n",
"91 48 \n",
"95 94 "
]
},
"execution_count": 33,
"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": 34,
"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": 35,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.axes._subplots.AxesSubplot at 0x7f57a5df52e8>"
]
},
"execution_count": 35,
"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 a helper function to parse response objects into **meta** and **results** dataframes\n",
"3. built a helper function to loop through multiple API calls and [concat]-enate a list of pages into a single useful dataframe\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",
"[concat]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.concat.html\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"
]
}
],
"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