├── .gitignore ├── Jupyter - Google Sheets.ipynb ├── README.md └── environment.yml /.gitignore: -------------------------------------------------------------------------------- 1 | .ipynb_checkpoints/ 2 | client_id.json 3 | Jupyter-and-Google-Sheet-584f47a17e35.json -------------------------------------------------------------------------------- /Jupyter - Google Sheets.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import pandas as pd\n", 10 | "import gspread\n", 11 | "from oauth2client.service_account import ServiceAccountCredentials\n", 12 | "from pandas.io.json import json_normalize" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 2, 18 | "metadata": {}, 19 | "outputs": [], 20 | "source": [ 21 | "## Connect to our service account\n", 22 | "scope = ['https://spreadsheets.google.com/feeds']\n", 23 | "credentials = ServiceAccountCredentials.from_json_keyfile_name('./Jupyter-and-Google-Sheet-584f47a17e35.json', scope)\n", 24 | "gc = gspread.authorize(credentials)" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 3, 30 | "metadata": {}, 31 | "outputs": [ 32 | { 33 | "data": { 34 | "text/plain": [ 35 | "[['Order',\n", 36 | " 'Candidate',\n", 37 | " 'Position',\n", 38 | " 'Start Date',\n", 39 | " 'End Date',\n", 40 | " 'Years of Experience',\n", 41 | " 'Points',\n", 42 | " '',\n", 43 | " '',\n", 44 | " '',\n", 45 | " '',\n", 46 | " '',\n", 47 | " '',\n", 48 | " '',\n", 49 | " '',\n", 50 | " '',\n", 51 | " '',\n", 52 | " '',\n", 53 | " ''],\n", 54 | " ['45',\n", 55 | " 'Donald Trump',\n", 56 | " 'President',\n", 57 | " '1/20/2017',\n", 58 | " '1/20/2021',\n", 59 | " '4.002739726',\n", 60 | " '104',\n", 61 | " '',\n", 62 | " '',\n", 63 | " '',\n", 64 | " '',\n", 65 | " '',\n", 66 | " '',\n", 67 | " '',\n", 68 | " '',\n", 69 | " '',\n", 70 | " '',\n", 71 | " '',\n", 72 | " ''],\n", 73 | " ['45',\n", 74 | " 'Donald Trump',\n", 75 | " 'Secretary of State',\n", 76 | " '',\n", 77 | " '',\n", 78 | " '0',\n", 79 | " '0',\n", 80 | " '',\n", 81 | " '',\n", 82 | " '',\n", 83 | " '',\n", 84 | " '',\n", 85 | " '',\n", 86 | " '',\n", 87 | " '',\n", 88 | " '',\n", 89 | " '',\n", 90 | " '',\n", 91 | " ''],\n", 92 | " ['45',\n", 93 | " 'Donald Trump',\n", 94 | " 'Secretary of Defense',\n", 95 | " '',\n", 96 | " '',\n", 97 | " '0',\n", 98 | " '0',\n", 99 | " '',\n", 100 | " '',\n", 101 | " '',\n", 102 | " '',\n", 103 | " '',\n", 104 | " '',\n", 105 | " '',\n", 106 | " '',\n", 107 | " '',\n", 108 | " '',\n", 109 | " '',\n", 110 | " ''],\n", 111 | " ['45',\n", 112 | " 'Donald Trump',\n", 113 | " 'Secretary of Treasury',\n", 114 | " '',\n", 115 | " '',\n", 116 | " '0',\n", 117 | " '0',\n", 118 | " '',\n", 119 | " '',\n", 120 | " '',\n", 121 | " '',\n", 122 | " '',\n", 123 | " '',\n", 124 | " '',\n", 125 | " '',\n", 126 | " '',\n", 127 | " '',\n", 128 | " '',\n", 129 | " ''],\n", 130 | " ['45',\n", 131 | " 'Donald Trump',\n", 132 | " 'Vice President',\n", 133 | " '',\n", 134 | " '',\n", 135 | " '0',\n", 136 | " '0',\n", 137 | " '',\n", 138 | " '',\n", 139 | " '',\n", 140 | " '',\n", 141 | " '',\n", 142 | " '',\n", 143 | " '',\n", 144 | " '',\n", 145 | " '',\n", 146 | " '',\n", 147 | " '',\n", 148 | " ''],\n", 149 | " ['45',\n", 150 | " 'Donald Trump',\n", 151 | " 'Attorney General',\n", 152 | " '',\n", 153 | " '',\n", 154 | " '0',\n", 155 | " '0',\n", 156 | " '',\n", 157 | " '',\n", 158 | " '',\n", 159 | " '',\n", 160 | " '',\n", 161 | " '',\n", 162 | " '',\n", 163 | " '',\n", 164 | " '',\n", 165 | " '',\n", 166 | " '',\n", 167 | " ''],\n", 168 | " ['45',\n", 169 | " 'Donald Trump',\n", 170 | " 'Military Supreme Commander',\n", 171 | " '',\n", 172 | " '',\n", 173 | " '0',\n", 174 | " '0',\n", 175 | " '',\n", 176 | " '',\n", 177 | " '',\n", 178 | " '',\n", 179 | " '',\n", 180 | " '',\n", 181 | " '',\n", 182 | " '',\n", 183 | " '',\n", 184 | " '',\n", 185 | " '',\n", 186 | " '']]" 187 | ] 188 | }, 189 | "execution_count": 3, 190 | "metadata": {}, 191 | "output_type": "execute_result" 192 | } 193 | ], 194 | "source": [ 195 | "##Get candidate data sheet from Google Drive\n", 196 | "spreadsheet_key = '1f0OwtmuTk1fTdhnn4tuvVcPCZjdb00D79dWw4RFhYs0'\n", 197 | "book = gc.open_by_key(spreadsheet_key)\n", 198 | "worksheet = book.worksheet(\"Candidate Data\")\n", 199 | "table = worksheet.get_all_values()\n", 200 | "table[:8]" 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "execution_count": 4, 206 | "metadata": {}, 207 | "outputs": [ 208 | { 209 | "data": { 210 | "text/html": [ 211 | "
\n", 212 | "\n", 225 | "\n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | " \n", 253 | " \n", 254 | " \n", 255 | " \n", 256 | " \n", 257 | " \n", 258 | " \n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 265 | " \n", 266 | " \n", 267 | " \n", 268 | " \n", 269 | " \n", 270 | " \n", 271 | " \n", 272 | " \n", 273 | " \n", 274 | " \n", 275 | " \n", 276 | " \n", 277 | " \n", 278 | " \n", 279 | " \n", 280 | " \n", 281 | " \n", 282 | " \n", 283 | " \n", 284 | " \n", 285 | " \n", 286 | " \n", 287 | " \n", 288 | " \n", 289 | " \n", 290 | "
OrderCandidatePositionStart DateEnd DateYears of ExperiencePoints
045Donald TrumpPresident2017-01-202021-01-204.00274104.0
145Donald TrumpSecretary of StateNaTNaT0.000000.0
245Donald TrumpSecretary of DefenseNaTNaT0.000000.0
345Donald TrumpSecretary of TreasuryNaTNaT0.000000.0
445Donald TrumpVice PresidentNaTNaT0.000000.0
\n", 291 | "
" 292 | ], 293 | "text/plain": [ 294 | " Order Candidate Position Start Date End Date \\\n", 295 | "0 45 Donald Trump President 2017-01-20 2021-01-20 \n", 296 | "1 45 Donald Trump Secretary of State NaT NaT \n", 297 | "2 45 Donald Trump Secretary of Defense NaT NaT \n", 298 | "3 45 Donald Trump Secretary of Treasury NaT NaT \n", 299 | "4 45 Donald Trump Vice President NaT NaT \n", 300 | "\n", 301 | " Years of Experience Points \n", 302 | "0 4.00274 104.0 \n", 303 | "1 0.00000 0.0 \n", 304 | "2 0.00000 0.0 \n", 305 | "3 0.00000 0.0 \n", 306 | "4 0.00000 0.0 " 307 | ] 308 | }, 309 | "execution_count": 4, 310 | "metadata": {}, 311 | "output_type": "execute_result" 312 | } 313 | ], 314 | "source": [ 315 | "##Convert table data into a dataframe\n", 316 | "df = pd.DataFrame(table[1:], columns=table[0])\n", 317 | "\n", 318 | "##Only keep columns we need\n", 319 | "df = df[['Order', 'Candidate', 'Position', 'Start Date', 'End Date', 'Years of Experience', 'Points']]\n", 320 | "\n", 321 | "##Convert number strings to floats and ints\n", 322 | "df = df.apply(pd.to_numeric, errors='ignore')\n", 323 | "\n", 324 | "##Convert date strings to datetime format\n", 325 | "df['End Date'] = pd.to_datetime(df['End Date'],infer_datetime_format=True)\n", 326 | "df['Start Date'] = pd.to_datetime(df['Start Date'],infer_datetime_format=True)\n", 327 | "\n", 328 | "df.head()" 329 | ] 330 | }, 331 | { 332 | "cell_type": "code", 333 | "execution_count": 5, 334 | "metadata": {}, 335 | "outputs": [ 336 | { 337 | "data": { 338 | "text/html": [ 339 | "
\n", 340 | "\n", 353 | "\n", 354 | " \n", 355 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | " \n", 366 | " \n", 367 | " \n", 368 | " \n", 369 | " \n", 370 | " \n", 371 | " \n", 372 | " \n", 373 | " \n", 374 | " \n", 375 | " \n", 376 | " \n", 377 | " \n", 378 | " \n", 379 | " \n", 380 | " \n", 381 | " \n", 382 | " \n", 383 | " \n", 384 | " \n", 385 | " \n", 386 | " \n", 387 | " \n", 388 | " \n", 389 | " \n", 390 | " \n", 391 | " \n", 392 | " \n", 393 | " \n", 394 | " \n", 395 | " \n", 396 | " \n", 397 | " \n", 398 | " \n", 399 | " \n", 400 | "
OrderYears of ExperiencePoints
Candidate
Abraham Lincoln166.336986114.00
Andrew Jackson719.884932246.85
Andrew Johnson1725.443836204.45
Barack Obama4412.054795208.55
Benjamin Harrison2312.887671137.70
\n", 401 | "
" 402 | ], 403 | "text/plain": [ 404 | " Order Years of Experience Points\n", 405 | "Candidate \n", 406 | "Abraham Lincoln 16 6.336986 114.00\n", 407 | "Andrew Jackson 7 19.884932 246.85\n", 408 | "Andrew Johnson 17 25.443836 204.45\n", 409 | "Barack Obama 44 12.054795 208.55\n", 410 | "Benjamin Harrison 23 12.887671 137.70" 411 | ] 412 | }, 413 | "execution_count": 5, 414 | "metadata": {}, 415 | "output_type": "execute_result" 416 | } 417 | ], 418 | "source": [ 419 | "## Do some manipulation of the data\n", 420 | "candidate_groups = df.groupby('Candidate')\n", 421 | "scores_df = candidate_groups.sum()\n", 422 | "scores_df['Order'] = candidate_groups.first()\n", 423 | "scores_df.head()" 424 | ] 425 | }, 426 | { 427 | "cell_type": "code", 428 | "execution_count": 6, 429 | "metadata": {}, 430 | "outputs": [ 431 | { 432 | "data": { 433 | "text/plain": [ 434 | "" 435 | ] 436 | }, 437 | "execution_count": 6, 438 | "metadata": {}, 439 | "output_type": "execute_result" 440 | } 441 | ], 442 | "source": [ 443 | "## Save the data back to a new sheet in the dataframe\n", 444 | "from df2gspread import df2gspread as d2g\n", 445 | "\n", 446 | "wks_name = 'Jupyter Manipulated Data'\n", 447 | "\n", 448 | "d2g.upload(scores_df, spreadsheet_key, wks_name, credentials=credentials, row_names=True)" 449 | ] 450 | }, 451 | { 452 | "cell_type": "code", 453 | "execution_count": null, 454 | "metadata": {}, 455 | "outputs": [], 456 | "source": [] 457 | } 458 | ], 459 | "metadata": { 460 | "kernelspec": { 461 | "display_name": "Python [conda env:JupSheets]", 462 | "language": "python", 463 | "name": "conda-env-JupSheets-py" 464 | }, 465 | "language_info": { 466 | "codemirror_mode": { 467 | "name": "ipython", 468 | "version": 2 469 | }, 470 | "file_extension": ".py", 471 | "mimetype": "text/x-python", 472 | "name": "python", 473 | "nbconvert_exporter": "python", 474 | "pygments_lexer": "ipython2", 475 | "version": "2.7.14" 476 | } 477 | }, 478 | "nbformat": 4, 479 | "nbformat_minor": 2 480 | } 481 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Jupyter-GoogleSheets 2 | This repo shows how to pass data between a google sheet and jupyter notebook. 3 | 4 | Follow the tutorial at [countingcalculi.com/explanations/google_sheets_and_jupyter_notebooks](https://goo.gl/ynSdVn) 5 | -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | name: JupSheets 2 | channels: 3 | - anaconda-fusion 4 | - defaults 5 | dependencies: 6 | - _nb_ext_conf=0.4.0=py27_1 7 | - anaconda-client=1.6.11=py27_0 8 | - appnope=0.1.0=py27hb466136_0 9 | - asn1crypto=0.24.0=py27_0 10 | - backports=1.0=py27hb4f9756_1 11 | - backports.shutil_get_terminal_size=1.0.0=py27hc9115de_2 12 | - backports_abc=0.5=py27h6972548_0 13 | - bleach=2.1.2=py27_0 14 | - ca-certificates=2017.08.26=ha1e5d58_0 15 | - certifi=2018.1.18=py27_0 16 | - cffi=1.11.4=py27h342bebf_0 17 | - chardet=3.0.4=py27h2842e91_1 18 | - clyent=1.2.2=py27hc0ae608_0 19 | - configparser=3.5.0=py27hc7edf1b_0 20 | - cryptography=2.1.4=py27hdbc5e8f_0 21 | - dbus=1.12.2=h5243cc1_1 22 | - decorator=4.2.1=py27_0 23 | - entrypoints=0.2.3=py27hd680fb1_2 24 | - enum34=1.1.6=py27hf475452_1 25 | - expat=2.2.5=hb8e80ba_0 26 | - functools32=3.2.3.2=py27h8ceab06_1 27 | - gettext=0.19.8.1=h15daf44_3 28 | - glib=2.53.6=h33f6a65_2 29 | - html5lib=1.0.1=py27h5233db4_0 30 | - icu=58.2=h4b95b61_1 31 | - idna=2.6=py27hedea723_1 32 | - intel-openmp=2018.0.0=h8158457_8 33 | - ipaddress=1.0.19=py27_0 34 | - ipykernel=4.8.2=py27_0 35 | - ipython=5.4.1=py27_2 36 | - ipython_genutils=0.2.0=py27h8b9a179_0 37 | - ipywidgets=7.1.2=py27_0 38 | - jinja2=2.10=py27h70b8dc5_0 39 | - jpeg=9b=he5867d9_2 40 | - jsonschema=2.6.0=py27hd9b497e_0 41 | - jupyter=1.0.0=py27_4 42 | - jupyter_client=5.2.2=py27_0 43 | - jupyter_console=5.2.0=py27h9702a86_1 44 | - jupyter_core=4.4.0=py27h5ea6ba4_0 45 | - libcxx=4.0.1=h579ed51_0 46 | - libcxxabi=4.0.1=hebd6815_0 47 | - libedit=3.1=hb4e282d_0 48 | - libffi=3.2.1=h475c297_4 49 | - libgfortran=3.0.1=h93005f0_2 50 | - libiconv=1.15=hdd342a3_7 51 | - libpng=1.6.34=he12f830_0 52 | - libsodium=1.0.15=hd9e47c5_0 53 | - markupsafe=1.0=py27hd3c86fa_1 54 | - mistune=0.8.3=py27_0 55 | - mkl=2018.0.1=hfbd8650_4 56 | - nb_anacondacloud=1.4.0=py27_0 57 | - nb_conda=2.2.1=py27h9a0a3a7_0 58 | - nb_conda_kernels=2.1.0=py27_0 59 | - nbconvert=5.3.1=py27h6455e4c_0 60 | - nbformat=4.4.0=py27hddc86d0_0 61 | - nbpresent=3.0.2=py27h73ae17d_1 62 | - ncurses=6.0=hd04f020_2 63 | - notebook=5.4.0=py27_0 64 | - numpy=1.14.1=py27h8a80b8c_1 65 | - openssl=1.0.2n=hdbc3d79_0 66 | - pandas=0.22.0=py27h0a44026_0 67 | - pandoc=1.19.2.1=ha5e8f32_1 68 | - pandocfilters=1.4.2=py27hed78c4e_1 69 | - pathlib2=2.3.0=py27he09da1e_0 70 | - pcre=8.41=hfb6ab37_1 71 | - pexpect=4.4.0=py27_0 72 | - pickleshare=0.7.4=py27h37e3d41_0 73 | - pip=9.0.1=py27h1567d89_4 74 | - prompt_toolkit=1.0.15=py27h4a7b9c2_0 75 | - ptyprocess=0.5.2=py27h70f6364_0 76 | - pycparser=2.18=py27h0d28d88_1 77 | - pygments=2.2.0=py27h1a556bb_0 78 | - pyopenssl=17.5.0=py27hfda213f_0 79 | - pyqt=5.6.0=py27hf21fe59_6 80 | - pysocks=1.6.7=py27h1cff6a6_1 81 | - python=2.7.14=hde5916a_29 82 | - python-dateutil=2.6.1=py27hd56c96b_1 83 | - pytz=2018.3=py27_0 84 | - pyyaml=3.12=py27ha7932d0_1 85 | - pyzmq=16.0.3=py27h91ccc67_0 86 | - qt=5.6.2=h9975529_14 87 | - qtconsole=4.3.1=py27hdc90b4f_0 88 | - readline=7.0=hc1231fa_4 89 | - requests=2.18.4=py27h9b2b37c_1 90 | - scandir=1.7=py27h1de35cc_0 91 | - send2trash=1.5.0=py27_0 92 | - setuptools=38.5.1=py27_0 93 | - simplegeneric=0.8.1=py27_2 94 | - singledispatch=3.4.0.3=py27he22c18d_0 95 | - sip=4.18.1=py27h6300f65_2 96 | - six=1.11.0=py27h7252ba3_1 97 | - sqlite=3.22.0=h3efe00b_0 98 | - ssl_match_hostname=3.5.0.1=py27h8780752_2 99 | - terminado=0.8.1=py27_1 100 | - testpath=0.3.1=py27h72d81a5_0 101 | - tk=8.6.7=h35a86e2_3 102 | - tornado=4.5.3=py27_0 103 | - traitlets=4.3.2=py27hcf08151_0 104 | - urllib3=1.22=py27hc3787e9_0 105 | - wcwidth=0.1.7=py27h817c265_0 106 | - webencodings=0.5.1=py27h19a9f58_1 107 | - wheel=0.30.0=py27h677a027_1 108 | - widgetsnbextension=3.1.4=py27_0 109 | - yaml=0.1.7=hc338f04_2 110 | - zeromq=4.2.2=ha360ad0_2 111 | - zlib=1.2.11=hf3cbc9b_2 112 | - pip: 113 | - backports-abc==0.5 114 | - backports.shutil-get-terminal-size==1.0.0 115 | - backports.ssl-match-hostname==3.5.0.1 116 | - df2gspread==0.2.5 117 | - google-api-python-client==1.6.2 118 | - gspread==0.6.2 119 | - httplib2==0.10.3 120 | - ipython-genutils==0.2.0 121 | - jupyter-client==5.2.2 122 | - jupyter-console==5.2.0 123 | - jupyter-core==4.4.0 124 | - nb-anacondacloud==1.4.0 125 | - nb-conda==2.2.1 126 | - nb-conda-kernels==2.1.0 127 | - oauth2client==4.1.2 128 | - prompt-toolkit==1.0.15 129 | - pyasn1==0.4.2 130 | - pyasn1-modules==0.2.1 131 | - pycrypto==2.6.1 132 | - rsa==3.4.2 133 | - uritemplate==3.0.0 134 | prefix: /anaconda/envs/JupSheets 135 | 136 | --------------------------------------------------------------------------------