Skip to content

Instantly share code, notes, and snippets.

@lorinc
Last active February 7, 2019 06:04
Show Gist options
  • Save lorinc/86167e71b095fa4c74030569342c2026 to your computer and use it in GitHub Desktop.
Save lorinc/86167e71b095fa4c74030569342c2026 to your computer and use it in GitHub Desktop.
a data munging challenge I had to solve at UBS
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Clean up a messy data source describing a hierarchical structure identified as follows.\n",
"\n",
" ¦ A ¦ B ¦ C ¦ D ¦\n",
" -----------------\n",
" ¦ x ¦ ¦ ¦ a ¦\n",
" ¦ ¦ x ¦ ¦ b ¦\n",
" ¦ ¦ ¦ x ¦ c ¦\n",
" ¦ ¦ ¦ x ¦ d ¦\n",
" ¦ x ¦ ¦ ¦ e ¦\n",
" ¦ ¦ x ¦ ¦ f ¦\n",
" ¦ ¦ ¦ x ¦ g ¦\n",
" ¦ ¦ ¦ x ¦ h ¦\n",
"\n",
"Generate unique IDs that also keep the hierarchical nature of the data.\n",
"\n",
" ¦ A ¦ B ¦ C ¦ D ¦ ID ¦\n",
" -------------------------\n",
" ¦ x ¦ ¦ ¦ a ¦ a ¦\n",
" ¦ ¦ x ¦ ¦ b ¦ a.b ¦\n",
" ¦ ¦ ¦ x ¦ c ¦ a.b.c ¦\n",
" ¦ ¦ ¦ x ¦ d ¦ a.b.d ¦\n",
" ¦ x ¦ ¦ ¦ e ¦ e ¦ <-- note, this is NOT e.b.d,\n",
" ¦ ¦ x ¦ ¦ f ¦ e.f ¦ so when parent changes\n",
" ¦ ¦ ¦ x ¦ g ¦ e.f.g ¦ fillna must not be applied\n",
" ¦ ¦ ¦ x ¦ h ¦ e.f.h ¦\n"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" <th>2</th>\n",
" <th>3</th>\n",
" <th>4</th>\n",
" <th>5</th>\n",
" <th>6</th>\n",
" <th>7</th>\n",
" <th>8</th>\n",
" <th>9</th>\n",
" <th>10</th>\n",
" <th>11</th>\n",
" <th>12</th>\n",
" <th>13</th>\n",
" <th>14</th>\n",
" <th>15</th>\n",
" <th>16</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>A</th>\n",
" <td>x</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>B</th>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td>x</td>\n",
" <td>x</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>C</th>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td>x</td>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td>x</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td>x</td>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td>x</td>\n",
" <td>x</td>\n",
" </tr>\n",
" <tr>\n",
" <th>D</th>\n",
" <td>x</td>\n",
" <td>a</td>\n",
" <td>b</td>\n",
" <td>c</td>\n",
" <td>1</td>\n",
" <td>2</td>\n",
" <td>d</td>\n",
" <td>3</td>\n",
" <td>4</td>\n",
" <td>y</td>\n",
" <td>e</td>\n",
" <td>5</td>\n",
" <td>6</td>\n",
" <td>f</td>\n",
" <td>7</td>\n",
" <td>8</td>\n",
" <td>9</td>\n",
" </tr>\n",
" <tr>\n",
" <th>expected</th>\n",
" <td>x</td>\n",
" <td>xa</td>\n",
" <td>xb</td>\n",
" <td>xc</td>\n",
" <td>xc1</td>\n",
" <td>xc2</td>\n",
" <td>xd</td>\n",
" <td>xd3</td>\n",
" <td>xd4</td>\n",
" <td>y</td>\n",
" <td>ye</td>\n",
" <td>ye5</td>\n",
" <td>ye6</td>\n",
" <td>yf</td>\n",
" <td>yf7</td>\n",
" <td>yf8</td>\n",
" <td>yf9</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" 0 1 2 3 4 5 6 7 8 9 10 11 12 \\\n",
"A x NaN NaN NaN NaN NaN NaN NaN NaN x NaN NaN NaN \n",
"B NaN x x x NaN NaN x NaN NaN NaN x NaN NaN \n",
"C NaN NaN NaN NaN x x NaN x x NaN NaN x x \n",
"D x a b c 1 2 d 3 4 y e 5 6 \n",
"expected x xa xb xc xc1 xc2 xd xd3 xd4 y ye ye5 ye6 \n",
"\n",
" 13 14 15 16 \n",
"A NaN NaN NaN NaN \n",
"B x NaN NaN NaN \n",
"C NaN x x x \n",
"D f 7 8 9 \n",
"expected yf yf7 yf8 yf9 "
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Testdata:\n",
"\n",
"import sys\n",
"\n",
"if sys.version_info[0] < 3:\n",
" from StringIO import StringIO\n",
"else:\n",
" from io import StringIO\n",
"import pandas as pd\n",
"\n",
"TESTDATA=StringIO(\"\"\"\n",
"A;B;C;D;expected\n",
"x;;;x;x\n",
";x;;a;xa\n",
";x;;b;xb\n",
";x;;c;xc\n",
";;x;1;xc1\n",
";;x;2;xc2\n",
";x;;d;xd\n",
";;x;3;xd3\n",
";;x;4;xd4\n",
"x;;;y;y\n",
";x;;e;ye\n",
";;x;5;ye5\n",
";;x;6;ye6\n",
";x;;f;yf\n",
";;x;7;yf7\n",
";;x;8;yf8\n",
";;x;9;yf9\"\"\")\n",
"\n",
"df = pd.read_csv(TESTDATA, sep=\";\", header=False)\n",
"\n",
"# I rotate results for readibility\n",
"df.transpose()"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" <th>2</th>\n",
" <th>3</th>\n",
" <th>4</th>\n",
" <th>5</th>\n",
" <th>6</th>\n",
" <th>7</th>\n",
" <th>8</th>\n",
" <th>9</th>\n",
" <th>10</th>\n",
" <th>11</th>\n",
" <th>12</th>\n",
" <th>13</th>\n",
" <th>14</th>\n",
" <th>15</th>\n",
" <th>16</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>A</th>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>B</th>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>C</th>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16\n",
"A 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0\n",
"B 1 1 1 1 0 0 1 0 0 1 1 0 0 1 0 0 0\n",
"C 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# challenge: map the cells where fillna stop - STEP1\n",
"# map cells that had something before them (inclusive)\n",
"(df.iloc[:,:3] == 'x').cumsum(axis=1).transpose()"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" <th>2</th>\n",
" <th>3</th>\n",
" <th>4</th>\n",
" <th>5</th>\n",
" <th>6</th>\n",
" <th>7</th>\n",
" <th>8</th>\n",
" <th>9</th>\n",
" <th>10</th>\n",
" <th>11</th>\n",
" <th>12</th>\n",
" <th>13</th>\n",
" <th>14</th>\n",
" <th>15</th>\n",
" <th>16</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>A</th>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>B</th>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>C</th>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>True</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" <td>False</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" 0 1 2 3 4 5 6 7 8 9 \\\n",
"A False True True True True True True True True False \n",
"B True False False False True True False True True True \n",
"C True True True True False False True False False True \n",
"\n",
" 10 11 12 13 14 15 16 \n",
"A True True True True True True True \n",
"B False True True False True True True \n",
"C True False False True False False False "
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# challenge: map the cells where fillna stop - STEP2\n",
"# create a boolean map for empty cells\n",
"((df.iloc[:,:3] == 'x') == False).transpose()"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" <th>2</th>\n",
" <th>3</th>\n",
" <th>4</th>\n",
" <th>5</th>\n",
" <th>6</th>\n",
" <th>7</th>\n",
" <th>8</th>\n",
" <th>9</th>\n",
" <th>10</th>\n",
" <th>11</th>\n",
" <th>12</th>\n",
" <th>13</th>\n",
" <th>14</th>\n",
" <th>15</th>\n",
" <th>16</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>A</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>B</th>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>C</th>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16\n",
"A 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n",
"B 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0\n",
"C 1 1 1 1 0 0 1 0 0 1 1 0 0 1 0 0 0"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# challenge: map the cells where fillna stop - STEP3\n",
"# these two together gives exactly what we wanted: points where ffill must stop\n",
"# - cells that was empty\n",
"# - AND had non-empty cells before them\n",
"((df.iloc[:,:3] == 'x').cumsum(axis=1) & ((df.iloc[:,:3] == 'x') == False)).transpose()"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>A</th>\n",
" <th>B</th>\n",
" <th>C</th>\n",
" <th>D</th>\n",
" <th>expected</th>\n",
" <th>result</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>x</td>\n",
" <td></td>\n",
" <td></td>\n",
" <td>x</td>\n",
" <td>x</td>\n",
" <td>x</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td></td>\n",
" <td>a</td>\n",
" <td>xa</td>\n",
" <td>xa</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td></td>\n",
" <td>b</td>\n",
" <td>xb</td>\n",
" <td>xb</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td></td>\n",
" <td>c</td>\n",
" <td>xc</td>\n",
" <td>xc</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td>1</td>\n",
" <td>xc1</td>\n",
" <td>xc1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td>2</td>\n",
" <td>xc2</td>\n",
" <td>xc2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td></td>\n",
" <td>d</td>\n",
" <td>xd</td>\n",
" <td>xd</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td>3</td>\n",
" <td>xd3</td>\n",
" <td>xd3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td>4</td>\n",
" <td>xd4</td>\n",
" <td>xd4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>x</td>\n",
" <td></td>\n",
" <td></td>\n",
" <td>y</td>\n",
" <td>y</td>\n",
" <td>y</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td></td>\n",
" <td>e</td>\n",
" <td>ye</td>\n",
" <td>ye</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td>5</td>\n",
" <td>ye5</td>\n",
" <td>ye5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td>6</td>\n",
" <td>ye6</td>\n",
" <td>ye6</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td></td>\n",
" <td>f</td>\n",
" <td>yf</td>\n",
" <td>yf</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td>7</td>\n",
" <td>yf7</td>\n",
" <td>yf7</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td>8</td>\n",
" <td>yf8</td>\n",
" <td>yf8</td>\n",
" </tr>\n",
" <tr>\n",
" <th>16</th>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>x</td>\n",
" <td>9</td>\n",
" <td>yf9</td>\n",
" <td>yf9</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" A B C D expected result\n",
"0 x x x x\n",
"1 NaN x a xa xa\n",
"2 NaN x b xb xb\n",
"3 NaN x c xc xc\n",
"4 NaN NaN x 1 xc1 xc1\n",
"5 NaN NaN x 2 xc2 xc2\n",
"6 NaN x d xd xd\n",
"7 NaN NaN x 3 xd3 xd3\n",
"8 NaN NaN x 4 xd4 xd4\n",
"9 x y y y\n",
"10 NaN x e ye ye\n",
"11 NaN NaN x 5 ye5 ye5\n",
"12 NaN NaN x 6 ye6 ye6\n",
"13 NaN x f yf yf\n",
"14 NaN NaN x 7 yf7 yf7\n",
"15 NaN NaN x 8 yf8 yf8\n",
"16 NaN NaN x 9 yf9 yf9"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# bool mask for empty cells that have non-empty cell before them\n",
"nofills = (df.iloc[:,:3] == 'x').cumsum(axis=1) & ((df.iloc[:,:3] == 'x') == False) > 0\n",
"\n",
"# fill these with empty strings\n",
"df[nofills] = ''\n",
"\n",
"# do what was obvious before we realized the ffill problem:\n",
"# replace 'x'es with values from column D, ffill up NaNs then concat together into a new column\n",
"df['result'] = df.iloc[:,:3].where(df.iloc[:,:3] != 'x', df.D, axis=0).ffill().apply(''.join, axis=1)\n",
"\n",
"df"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment