Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rmoff/6f7d3138efdbb322d8543d35912c99ab to your computer and use it in GitHub Desktop.
Save rmoff/6f7d3138efdbb322d8543d35912c99ab to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[@rmoff](http://twitter.com/rmoff/) / July 13, 2016"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Preparation"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Instantiate BDD shell to get access to BDD datasets"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"execfile('ipython/00-bdd-shell-init.py')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"_Import readline is necessary to workaround the error:_\n",
"\n",
" /u01/anaconda2/lib/libreadline.so.6: undefined symbol: PC"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import readline"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Import the RPY2 environment"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"%load_ext rpy2.ipython"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Load dataset from BDD"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"List all BDD datasets"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Name: media_demo_customer\tKey:edp_cli_edp_2c7f41ee-65bf-43ac-8bb4-5b6b59a55d75\n",
"Name: movie_genre\tKey:default_edp_7d4c18a5-6f02-4067-9f63-91f950078b1e\n",
"Name: media_demo_customer\tKey:default_edp_89c616b6-aa10-4827-aa82-1e9c3fcc419e\n",
"Name: yelp_tip\tKey:edp_cli_edp_69567747-4d2e-451e-9127-85a00eaafc21\n",
"Name: yelp_checkin\tKey:edp_cli_edp_a544fb15-6ee7-4494-941d-c8f036049da1\n",
"Name: yelp_business\tKey:edp_cli_edp_6f576d12-a1e4-4d91-b489-76cb3bcc40e4\n",
"Name: media_demo_movielog\tKey:edp_cli_edp_1c5465a1-75bd-4f49-9e10-c552e2c0ff65\n",
"Name: uber_rides\tKey:edp_cli_edp_f61a3a88-b773-4c79-a06e-e7e380fabc73\n",
"Name: media_demo_movielog\tKey:default_edp_f343a63a-4cc3-449c-a0a0-d4b50c3d0849\n",
"Name: us_weather_hourly\tKey:edp_cli_edp_09f2f24b-5311-4aee-9ae7-c492724772da\n",
"Name: us_weather_daily\tKey:edp_cli_edp_ea538365-4c5c-4446-b7e6-107d7ea659d1\n",
"Name: Weather - US Hourly \tKey:default_edp_595acd7d-e57f-492c-b093-cb34535acf84\n",
"Name: nyc_parking\tKey:edp_cli_edp_9cbffd17-4836-4743-a1ed-48e8d4f71d0b\n",
"Name: us_weather_station\tKey:edp_cli_edp_59419b0a-f2ca-4317-bb87-1925422ce464\n",
"Name: Weather - US Hourly \tKey:default_edp_63c32d8d-f4c6-490e-9f83-91b84eaf1ec3\n",
"Name: nyc_parking\tKey:default_edp_b48b2516-b9d0-49fb-8520-d7642536c02b\n",
"Name: us_weather_daily\tKey:edp_cli_edp_b7c60e0e-4260-4026-a756-c81491ab7723\n",
"Name: nyc_taxi\tKey:edp_cli_edp_8d6fd230-8e99-449c-9480-0c2bddc4f6dc\n",
"Name: yelp_review\tKey:edp_cli_edp_8684a9d3-f9be-440c-b722-71ff56ddc79e\n",
"Name: media_3rdparty_activity\tKey:default_edp_ae82f0cb-5a27-42c5-a423-c726f0f256c9\n",
"Name: yelp_business\tKey:edp_cli_edp_13e40a3f-cafc-464d-a794-48d5a2badda4\n",
"Name: yelp_review\tKey:edp_cli_edp_46db102d-a83c-4b5a-aa32-9356d0f4a2ed\n",
"Name: yelp_review\tKey:edp_cli_edp_187cde93-c926-4dde-94c1-5f2f9d0c5f9e\n",
"Name: nyc_taxi\tKey:edp_cli_edp_ff455305-0f99-4630-b87c-465fd58f7141\n",
"Name: yelp_reviews_with_business\tKey:default_edp_3ea4c66d-d8f6-41a0-b390-4476a58b566b\n",
"Name: nyc_taxi\tKey:default_edp_102132ec-0f3f-4900-a26c-3d6437a81412\n",
"Name: yelp_business_with_geo2\tKey:default_edp_32676f15-4884-4ca4-9d69-38dee3d92c29\n",
"Name: zzscrap\tKey:edp_cli_edp_61e47f75-bca6-4363-9fd4-5693d97aa382\n",
"Name: yelp_review\tKey:edp_cli_edp_b178ea4d-ce72-4748-80e4-5cb52e00752c\n",
"Name: yelp_review\tKey:default_edp_c5437c7a-f2a2-4835-89b4-d2fb253f7976\n",
"Name: us_weather_station\tKey:edp_cli_edp_52fa0875-e636-439e-b038-a5c16b25786b\n",
"Name: yelp_academic_dataset_tip_small\tKey:edp_cli_edp_f2322122-b4b7-4b9d-9a0e-f97f5e1e4a93\n",
"Name: us_weather_daily\tKey:edp_cli_edp_53410fa4-1e95-47bb-a344-25e7f118f9e5\n",
"Name: yelp_tip\tKey:edp_cli_edp_cabcd19f-a321-45ba-a76a-d2635a3d0c6c\n",
"Name: nyc_taxi_transformed\tKey:default_edp_7b44eebb-d2c3-472d-8b82-7a067211b497\n",
"Name: yelp_checkin\tKey:edp_cli_edp_1e4a698f-e100-496c-8a72-def2ce739f30\n",
"Name: us_weather_hourly\tKey:edp_cli_edp_a46bdea0-4d75-4fc8-a140-49d02fd644ff\n",
"Name: US Weather - Hourly \tKey:default_edp_ff8b3396-66f2-41c1-a6a3-241bc86ebd5e\n",
"Name: us_weather_hourly\tKey:default_edp_33fe4e43-649b-467a-bda0-d3ed4cf8bcaf\n",
"Name: nyc_taxi\tKey:default_edp_1350a5f3-019a-473a-88bf-295c60e2b804\n",
"Name: us_weather_daily\tKey:default_edp_9675d47f-8571-42df-9764-a3535a850f8d\n",
"Name: business_review_summary\tKey:default_edp_7ddc3011-ce61-4c46-80fa-788c818ebd12\n",
"Name: nyc_taxi\tKey:edp_cli_edp_96eb196a-558e-469f-bf9c-7c2570ae9fbb\n",
"Name: US Weather - Hourly \tKey:default_edp_17627e51-dfc7-4d3f-8187-8b8a4b79ae73\n",
"Name: us_weather_station\tKey:edp_cli_edp_56bdf409-01a5-40c5-bd48-da04cd6039c8\n"
]
}
],
"source": [
"dss = bc.datasets()\n",
"for ds in dss:\n",
" print('Name: %s\\tKey:%s'%(ds.properties()['displayName'] ,ds.properties()['databaseKey'] ))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Load dataset to spark dataframe"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"ds = dss.dataset('edp_cli_edp_8d6fd230-8e99-449c-9480-0c2bddc4f6dc')"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"root\n",
" |-- vendorid: long (nullable = true)\n",
" |-- tpep_pickup_datetime: long (nullable = true)\n",
" |-- tpep_dropoff_datetime: long (nullable = true)\n",
" |-- passenger_count: long (nullable = true)\n",
" |-- trip_distance: double (nullable = true)\n",
" |-- pickup_longitude: double (nullable = true)\n",
" |-- pickup_latitude: double (nullable = true)\n",
" |-- ratecodeid: long (nullable = true)\n",
" |-- store_and_fwd_flag: string (nullable = true)\n",
" |-- dropoff_longitude: double (nullable = true)\n",
" |-- dropoff_latitude: double (nullable = true)\n",
" |-- payment_type: long (nullable = true)\n",
" |-- fare_amount: double (nullable = true)\n",
" |-- extra: double (nullable = true)\n",
" |-- mta_tax: double (nullable = true)\n",
" |-- tip_amount: double (nullable = true)\n",
" |-- tolls_amount: double (nullable = true)\n",
" |-- improvement_surcharge: double (nullable = true)\n",
" |-- total_amount: double (nullable = true)\n",
" |-- PRIMARY_KEY: string (nullable = false)\n",
"\n"
]
}
],
"source": [
"spark_df = ds.to_spark()\n",
"spark_df.printSchema()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Convert spark dataframe to pandas"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import pandas as pd\n",
"pandas_df = spark_df.toPandas()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Pass dataframe to R\n",
"\n",
"_For more information see [rpy2 documentation](http://rpy.sourceforge.net/rpy2/doc-dev/html/interactive.html)_"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Pass Python variable to R using `-i`, and then do some R stuff"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/u01/anaconda2/lib/python2.7/site-packages/rpy2/robjects/pandas2ri.py:57: UserWarning: Error while trying to convert the column \"store_and_fwd_flag\". Fall back to string conversion. The error is: Conversion 'py2ri' not defined for objects of type '<type 'NoneType'>'\n",
" (name, str(e)))\n"
]
},
{
"data": {
"text/plain": [
" vendorid tpep_pickup_datetime tpep_dropoff_datetime passenger_count\n",
" Min. :1.000 Min. :1.420e+12 Min. :1.420e+12 Min. :0.000 \n",
" 1st Qu.:1.000 1st Qu.:1.427e+12 1st Qu.:1.427e+12 1st Qu.:1.000 \n",
" Median :2.000 Median :1.435e+12 Median :1.435e+12 Median :1.000 \n",
" Mean :1.525 Mean :1.435e+12 Mean :1.435e+12 Mean :1.679 \n",
" 3rd Qu.:2.000 3rd Qu.:1.443e+12 3rd Qu.:1.443e+12 3rd Qu.:2.000 \n",
" Max. :2.000 Max. :1.452e+12 Max. :1.452e+12 Max. :9.000 \n",
" NA's :12 NA's :12 NA's :12 NA's :12 \n",
" trip_distance pickup_longitude pickup_latitude ratecodeid \n",
" Min. : 0.00 Min. :-121.93 Min. :-58.43 Min. : 1.000 \n",
" 1st Qu.: 1.00 1st Qu.: -73.99 1st Qu.: 40.74 1st Qu.: 1.000 \n",
" Median : 1.71 Median : -73.98 Median : 40.75 Median : 1.000 \n",
" Mean : 3.04 Mean : -72.80 Mean : 40.10 Mean : 1.041 \n",
" 3rd Qu.: 3.20 3rd Qu.: -73.97 3rd Qu.: 40.77 3rd Qu.: 1.000 \n",
" Max. :67468.40 Max. : 133.82 Max. : 62.77 Max. :99.000 \n",
" NA's :12 NA's :12 NA's :12 NA's :12 \n",
" store_and_fwd_flag dropoff_longitude dropoff_latitude payment_type \n",
" N :992336 Min. :-121.93 Min. : 0.00 Min. :1.00 \n",
" None: 12 1st Qu.: -73.99 1st Qu.:40.73 1st Qu.:1.00 \n",
" Y : 8218 Median : -73.98 Median :40.75 Median :1.00 \n",
" Mean : -72.85 Mean :40.13 Mean :1.38 \n",
" 3rd Qu.: -73.96 3rd Qu.:40.77 3rd Qu.:2.00 \n",
" Max. : 0.00 Max. :44.56 Max. :5.00 \n",
" NA's :12 NA's :12 NA's :12 \n",
" fare_amount extra mta_tax tip_amount \n",
" Min. :-170.00 Min. :-1.0000 Min. :-1.7000 Min. : 0.000 \n",
" 1st Qu.: 6.50 1st Qu.: 0.0000 1st Qu.: 0.5000 1st Qu.: 0.000 \n",
" Median : 9.50 Median : 0.0000 Median : 0.5000 Median : 1.160 \n",
" Mean : 12.89 Mean : 0.3141 Mean : 0.4977 Mean : 1.699 \n",
" 3rd Qu.: 14.50 3rd Qu.: 0.5000 3rd Qu.: 0.5000 3rd Qu.: 2.300 \n",
" Max. : 750.00 Max. :49.6000 Max. :52.7500 Max. :360.000 \n",
" NA's :12 NA's :12 NA's :12 NA's :12 \n",
" tolls_amount improvement_surcharge total_amount PRIMARY_KEY \n",
" Min. : -5.5400 Min. :-0.3000 Min. :-170.80 0-0-0 : 1 \n",
" 1st Qu.: 0.0000 1st Qu.: 0.3000 1st Qu.: 8.75 0-0-1 : 1 \n",
" Median : 0.0000 Median : 0.3000 Median : 11.80 0-0-10 : 1 \n",
" Mean : 0.3072 Mean : 0.2983 Mean : 16.01 0-0-100 : 1 \n",
" 3rd Qu.: 0.0000 3rd Qu.: 0.3000 3rd Qu.: 17.80 0-0-1000: 1 \n",
" Max. :503.0500 Max. : 0.3000 Max. : 760.05 0-0-1001: 1 \n",
" NA's :12 NA's :12 NA's :12 (Other) :1000560 \n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%R -i pandas_df\n",
"\n",
"R.df <- pandas_df\n",
"\n",
"summary(R.df)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Do an R plot, and show how R libraries can be used"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/u01/anaconda2/lib/python2.7/site-packages/rpy2/rinterface/__init__.py:185: RRuntimeWarning: \n",
"Attaching package: ‘dplyr’\n",
"\n",
"\n",
" warnings.warn(x, RRuntimeWarning)\n",
"/u01/anaconda2/lib/python2.7/site-packages/rpy2/rinterface/__init__.py:185: RRuntimeWarning: The following objects are masked from ‘package:stats’:\n",
"\n",
" filter, lag\n",
"\n",
"\n",
" warnings.warn(x, RRuntimeWarning)\n",
"/u01/anaconda2/lib/python2.7/site-packages/rpy2/rinterface/__init__.py:185: RRuntimeWarning: The following objects are masked from ‘package:base’:\n",
"\n",
" intersect, setdiff, setequal, union\n",
"\n",
"\n",
" warnings.warn(x, RRuntimeWarning)\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAeAAAAHgCAIAAADytinCAAAgAElEQVR4nOzdd3gc1bk/8PdM2b6r\nlbRqVrHVJfeGhY2LjE2N6VwCCSQkcAlJCDgBEgK/gAMh9+aGa/AFErDJJYGEgJ1QQjGm2rhhjBu2\nVW31Lm3vOzPn/P5YI3RxkayyM7bez6PnQTue3fOexfrq+OyZM4QxBgghhLSHU7sAhBBCJ4YBjRBC\nGoUBjRBCGoUBjRBCGiWo1XAwGBzimaIoyrKsyoeZPM8ripL4dgFAp9PFYjFVmlar14QQQRAkSUp8\n06BerzmO4zhOluXEN00IIYRQSkf4OmazeVTqQcdTLaDD4fAQz9Tr9ZIkqfJzazabh17nqDft8/lU\n+bWkVq95njcYDD6fL/FNg3q91uv1er1erTdcEIRoNDrC18GAHjs4xYEQQhqFAY0QQhqFAY0QQhqF\nAY0QQhqFAY0QQhqFAY0QQhqFAY0QQhqFAY0QQhqFAY0QQhqFAY0QQhqFAY0QQhqFAY0QQhqFAY0Q\nQhqFAY0QQhqFAY0QQhqFAY0QQhql2ob9Q3S0pbN7f63FqC8vzBEFrVeLEEKjSNOR19bVu/aVdwry\nJvgDoR6ne/mCWWpXhBBCiaPpKY7Wzr4MR7JOFG0W0ztbdqty/yeEEFKLpgPabjMHgmEAkGVl2fyZ\nhBC1K0IIocTRdECX5ucsrZhRfbSlIC/r3JnlapeDEEIJpek5aI7jFp0z9bILFgaDQVXu6o0QQirS\n9AgaIYTGMwxohBDSKAxohBDSKAxohBDSKAxohBDSKAxohBDSKAxohBDSKAxohBDSKAxohBDSKAxo\nhBDSKAxohBDSKAxohBDSKAxohBDSKAxohBDSKAxohBDSKAxohBDSKAxohBDSKAxohBDSKAxohBDS\nKAxohBDSKAxohBDSKAxohBDSKAxohBDSKMIYU6XhcDg8xDP1er0kSZTSMa3nhERRlCQp8e0CgNFo\njEQiqvzfUavXHMfpdLpIJJL4pkG9XvM8z/N8LBZLfNMcxxFCFEUZ4esYjcZRqQcdT1Cr4WAwOMQz\nRVGMRCKq/PCYzeah1zm6jEZjMBhUJaDV6jXP86IoqvWGq9VrvV6v1+vVesMFQYhGoyN8HQzosYNT\nHAghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0Agh\npFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY\n0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0Agh\npFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY\n0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0AghpFEY0Agh\npFEY0AghpFHCSJ7sdrvXrl0ry7Isy5dffnl6evozzzwjiqIkSbfffjsADHyYnZ09SjUjhNC4MKKA\n/tOf/lRRUVFZWRkOhz0ez7PPPrts2bLKysrNmzevW7cOAAY+XLVq1eiUjBBC48OIAvrAgQMpKSnP\nPvtsamrqj370o9ra2jvuuAMApk6dunbtWsbYwIfxp1RXV/v9fgAoLS0dYiuEEEEYUZ3DxnGcKIqq\nNA0AoigyxhLfrlq95nkeANR6w1Xs9ThsGg3RiIIvFAo5HI61a9d+8skna9asYYwRQuJ/RCkFgK89\nBIBXX321pqaG47g//elPQ2yF4ziDwaBWVMVTQxUmk0mVdtXqNSGE4ziz2Zz4pmFc9jr+46nT6RLf\nNBqiEQX0pEmTJk+ebLVay8vL169fX1JSUl1dvXDhwpqamrKyMkrpwIfxpzzwwAPxb/r6+obYit1u\nDwaDkiSNpNThMZvNwWAw8e0CgMPh8Hq9qvxaUqvXPM8nJSV5PJ7ENw3q9Vqv1+v1ep/Pl/imeZ4X\nBCEajY7wdRwOx6jUg443ooD+8Y9/vHbtWlEUo9HoPffck5KSsm7dup07d4ZCodtuu40xNvDhaFWM\nEELjBFFljAY4gh6Mw+FwOp3jcATtcrkS3zTgCHoEcAQ9dnAdNEIIaRQGNEIIaRQGNEIIaRQGNEII\naZQ6F4AM3Rf1LW5/HQE2u2yixWRQuxyEEEocTQf00bbu1z7anZ+T6Q8EI9HohfOnq10RQggljqan\nOHpdvmSrCQAMet0Huw6ptSIQIYRUoemATkuxuXxBxlgkGlteMbX/wnGEEBoPND3FUZiT8W8XnNvn\nDYk8mVGSp3Y5CCGUUJoOaACYUpij4pWECCGkIk1PcSCE0HiGAY0QQhqFAY0QQhqFAY0QQhqFAY0Q\n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\nyWncNFZRlHvuuWfsSkEInbUYfHXT2CF/DVzEwRiz2+3btm3btm1bPJ0B4M4777z55pvfeuutm2++\n+a677lKna2NpkIB+/PHH9Xp9fHJDEIS9e/cmpiyE0NlE4MmV8wriX8kmEahysq/8NEv/mQNfobu7\nu66uzuFwFBcXf/jhh/GDu3btWrJkCQAsWbJk165dKnRsjA0yxfHCCy8cPnz4wQcffOKJJz755JND\nhw4lpiyE0NlElulrO2qHcmZDp7uh0x3//q7L5/Yf5zhu1apVV1111d/+9rdbb721sbERACil/R+M\nqbIj8VgbZATt9XqLiooqKys/++yza6+9tv8XF0IIDR0DNowpDjZgjsPtdmdkZNhstsrKyv7tsysq\nKrZv3w4AO3bsmD9/vjp9G0uDjKDNZvNzzz03ffr01atXl5WVNTc3J6YshNBZZoQfEubm5j700ENr\n1qxxu93PP/88ADgcju3bt69cufK1117zer1PPvnkKFWqIYME9K9//evHHnts27ZtADBnzpxHHnkE\nAAghuLoDIXQaRnwloclkevnllwceid/0Y+PGjSMqTNsGCeirr7766quvBoD169cnpB6E0NkJryQc\nBtxFHiE09nDD/mHBgEYIJQJeuj0MGNAIoTEXX8WhdhVnHgxohNDYYziCHg4MaIRQAjDG8EPC0zac\ngMY1dgih0zS8ZXbjPWoGuZIwEAjcdddd5eXlVqv12Wef3bJlS2LKQgidTRgb1j0Jx3s+DxbQt956\na25u7ieffBIIBCorKx9++OHElIUQOsvghv3DMMgUxxdffNF/9U5JSUlTU9OYV4QQOvvgOuhhGWQE\nPWXKlEcffbShoQEA3n333eTk5IRUdeaJxqQ+t0+W8WMQhE6IMaqc7pfaNatvkBH0888//8gjj1x4\n4YUGg+Hee++N71GCvqaxrevJF/9lNhr8geBDd96UbLOoXRFCGoPL7IZlkIBesmTJRx999Lvf/S4x\n1YwcY6y926koSk5WGs+dxv1iRuJwfXNhXhZHSNRu/aKmYcm86YlpF6EzB05xDMcgEfb973//iSee\ncLlcialmhBhjH+7c/+zL7zz/6nsbt+yWE7WBd//NdAlHKB33HzwjdByGHxIOyyABfccdd6xatSo1\nNfWMuKu3LxD6cMe+CekpGanJew7Vt3f1JabdkknZjW1dvS5vU2v3tJJJiWkUoTPKcDbsV7tm9Z1V\n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\n9M1vfnPu3Lm33Xbb/v37p0KrlVLd3d1f+tKXampq7rnnns7OzqnQam3C8nqIo62trbW1FQBaW1v3\n7Nkz2dU5VZqbm2+55ZZDXx7R6o/qTSgsLLzxxhsBYNeuXTNnzpwiraaUXnjhhb/4xS++9rWvffnL\nX54irdYmLK+HOBCREDL+Wik1uZU5bY5u9UfyJhiG4TjO+vXr/X7/N77xjauuumoqtHrcFVdc0dLS\ncu+9906Rn7U2YXndg25qatq1axcA7N69u6WlZbKrc5oc0eqP6k1wXff222//zGc+c/311/t8vinS\n6lQq9c1vfpMQMm3atGw2O0VarU1YXk+z6+3tvfvuu4PBYDabvfbaa6uqqia7RqfQRRdd9PDDD8NR\nrUbEj+RN2LZt25133llWVjb+5Ve/+tWp0GoA+PWvf71jx45sNnvppZdOnz59irRam5i8DtCapmlT\nWV4PcWiapk1lOkBrmqblKR2gNU3T8pQO0No73HDDDeMvDs33ygeHaqVpU4p+SKi9AyEHfyVs2/b5\nfJNdnYMO1UrTphTdg9bedsUVVwDA+Apjv98PAISQW2+9debMmStXrty/f//Rb3nooYfmzZvX0NCw\nePHiO++8c/wgIeSmm26qr6+/+eabL7/88qampttvvx0AYrHYFVdcMXPmzObm5iuvvDIWi8FhXfXD\nX3z3u9+dPXv2P/3TPx1RK02bWlDTDnPoV2L8BQDcdtttiPgP//APF1988dHnL1++/K677kLE9vZ2\ny7IOvfeRRx7p6OgYf9He3l5QUICIX/ziF2+88UYhhBDixhtvvOqqq44ucfzF7373u7179x5+wVPW\nYk3LX/qTo/YOhwYTxl8QQjo7O+vr69vb25ctWzY6OnrE+Uqpl19+eceOHRs2bPjVr3516L2u6xqG\ncfgLRCwpKdm1a1dpaSkADA0NzZ07d3Bw8IgSx1/EYrHCwsKjv6VpU4oe4tCOC2NMSnn08csuu2z9\n+vUVFRXr168//LhhGEe8GHf4OMbhFxwbGzv8tMLCwpNSbU37UNMBWjvSEYH4gQceAID77rtv1apV\nR5/85JNPfv/737/wwgs3btx49HuPcMEFF3zve99TSkkpv/e9761btw4ATNPct2/fhg0bTqhWmjYV\n6ACtvcOaNWuO2EC9t7e3sbHxySefPPQM8HC33nrr6tWrV65cuWPHjtWrV998883vc/E77rhjZGSk\npaWlpaUlHo/fcccdAPCtb31r3bp1r7766gnVStOmAj20p70fPfiraZMor/NBa/nmXVev6AiuaaeI\nDtDa+2lvbz/8Sx2LNe100h9gNU3T8pR+SKhpmpandIDWNE3LUzpAa5qm5SkdoDVN0/LU/wfhfdfK\nDb6DKAAAAABJRU5ErkJggg==\n"
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%R\n",
"\n",
"library(dplyr)\n",
"library(ggplot2)\n",
"\n",
"R.df %>%\n",
" filter(fare_amount > 0) %>%\n",
" ggplot(aes(y=fare_amount, x=tip_amount,color=passenger_count)) + \n",
" geom_point(alpha=0.5 ) "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Modify the dataframe and pass it back to Python context"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"%%R -o R_output\n",
"R_output <-\n",
" R.df %>%\n",
" mutate(foo = 'bar')"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"Int64Index: 1000566 entries, 1 to 1000566\n",
"Data columns (total 21 columns):\n",
"vendorid 1000554 non-null float64\n",
"tpep_pickup_datetime 1000554 non-null float64\n",
"tpep_dropoff_datetime 1000554 non-null float64\n",
"passenger_count 1000554 non-null float64\n",
"trip_distance 1000554 non-null float64\n",
"pickup_longitude 1000554 non-null float64\n",
"pickup_latitude 1000554 non-null float64\n",
"ratecodeid 1000554 non-null float64\n",
"store_and_fwd_flag 1000566 non-null object\n",
"dropoff_longitude 1000554 non-null float64\n",
"dropoff_latitude 1000554 non-null float64\n",
"payment_type 1000554 non-null float64\n",
"fare_amount 1000554 non-null float64\n",
"extra 1000554 non-null float64\n",
"mta_tax 1000554 non-null float64\n",
"tip_amount 1000554 non-null float64\n",
"tolls_amount 1000554 non-null float64\n",
"improvement_surcharge 1000554 non-null float64\n",
"total_amount 1000554 non-null float64\n",
"PRIMARY_KEY 1000566 non-null object\n",
"foo 1000566 non-null object\n",
"dtypes: float64(18), object(3)\n",
"memory usage: 167.9+ MB\n"
]
}
],
"source": [
"R_output.info()"
]
},
{
"cell_type": "code",
"execution_count": 12,
"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>vendorid</th>\n",
" <th>tpep_pickup_datetime</th>\n",
" <th>tpep_dropoff_datetime</th>\n",
" <th>passenger_count</th>\n",
" <th>trip_distance</th>\n",
" <th>pickup_longitude</th>\n",
" <th>pickup_latitude</th>\n",
" <th>ratecodeid</th>\n",
" <th>store_and_fwd_flag</th>\n",
" <th>dropoff_longitude</th>\n",
" <th>...</th>\n",
" <th>payment_type</th>\n",
" <th>fare_amount</th>\n",
" <th>extra</th>\n",
" <th>mta_tax</th>\n",
" <th>tip_amount</th>\n",
" <th>tolls_amount</th>\n",
" <th>improvement_surcharge</th>\n",
" <th>total_amount</th>\n",
" <th>PRIMARY_KEY</th>\n",
" <th>foo</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2.0</td>\n",
" <td>1.421774e+12</td>\n",
" <td>1.421776e+12</td>\n",
" <td>1.0</td>\n",
" <td>6.32</td>\n",
" <td>-73.978897</td>\n",
" <td>40.766941</td>\n",
" <td>1.0</td>\n",
" <td>N</td>\n",
" <td>-73.988052</td>\n",
" <td>...</td>\n",
" <td>1.0</td>\n",
" <td>26.5</td>\n",
" <td>1.0</td>\n",
" <td>0.5</td>\n",
" <td>5.50</td>\n",
" <td>0.0</td>\n",
" <td>0.3</td>\n",
" <td>33.80</td>\n",
" <td>0-0-4</td>\n",
" <td>bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>1.0</td>\n",
" <td>1.421327e+12</td>\n",
" <td>1.421328e+12</td>\n",
" <td>1.0</td>\n",
" <td>0.90</td>\n",
" <td>-73.964127</td>\n",
" <td>40.792534</td>\n",
" <td>1.0</td>\n",
" <td>N</td>\n",
" <td>-73.952820</td>\n",
" <td>...</td>\n",
" <td>1.0</td>\n",
" <td>5.5</td>\n",
" <td>0.0</td>\n",
" <td>0.5</td>\n",
" <td>1.85</td>\n",
" <td>0.0</td>\n",
" <td>0.3</td>\n",
" <td>8.15</td>\n",
" <td>0-0-9</td>\n",
" <td>bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>1.0</td>\n",
" <td>1.421831e+12</td>\n",
" <td>1.421832e+12</td>\n",
" <td>1.0</td>\n",
" <td>2.40</td>\n",
" <td>-73.996017</td>\n",
" <td>40.738476</td>\n",
" <td>1.0</td>\n",
" <td>N</td>\n",
" <td>-73.971405</td>\n",
" <td>...</td>\n",
" <td>1.0</td>\n",
" <td>12.5</td>\n",
" <td>0.0</td>\n",
" <td>0.5</td>\n",
" <td>2.66</td>\n",
" <td>0.0</td>\n",
" <td>0.3</td>\n",
" <td>15.96</td>\n",
" <td>0-0-14</td>\n",
" <td>bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>2.0</td>\n",
" <td>1.421320e+12</td>\n",
" <td>1.421322e+12</td>\n",
" <td>1.0</td>\n",
" <td>5.65</td>\n",
" <td>-73.976395</td>\n",
" <td>40.739620</td>\n",
" <td>1.0</td>\n",
" <td>N</td>\n",
" <td>-73.950279</td>\n",
" <td>...</td>\n",
" <td>1.0</td>\n",
" <td>22.0</td>\n",
" <td>0.0</td>\n",
" <td>0.5</td>\n",
" <td>4.40</td>\n",
" <td>0.0</td>\n",
" <td>0.3</td>\n",
" <td>27.20</td>\n",
" <td>0-0-19</td>\n",
" <td>bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>1.0</td>\n",
" <td>1.422436e+12</td>\n",
" <td>1.422436e+12</td>\n",
" <td>1.0</td>\n",
" <td>0.70</td>\n",
" <td>-73.975975</td>\n",
" <td>40.761230</td>\n",
" <td>1.0</td>\n",
" <td>N</td>\n",
" <td>-73.979774</td>\n",
" <td>...</td>\n",
" <td>1.0</td>\n",
" <td>6.0</td>\n",
" <td>0.0</td>\n",
" <td>0.5</td>\n",
" <td>1.70</td>\n",
" <td>0.0</td>\n",
" <td>0.3</td>\n",
" <td>8.50</td>\n",
" <td>0-0-24</td>\n",
" <td>bar</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5 rows × 21 columns</p>\n",
"</div>"
],
"text/plain": [
" vendorid tpep_pickup_datetime tpep_dropoff_datetime passenger_count \\\n",
"1 2.0 1.421774e+12 1.421776e+12 1.0 \n",
"2 1.0 1.421327e+12 1.421328e+12 1.0 \n",
"3 1.0 1.421831e+12 1.421832e+12 1.0 \n",
"4 2.0 1.421320e+12 1.421322e+12 1.0 \n",
"5 1.0 1.422436e+12 1.422436e+12 1.0 \n",
"\n",
" trip_distance pickup_longitude pickup_latitude ratecodeid \\\n",
"1 6.32 -73.978897 40.766941 1.0 \n",
"2 0.90 -73.964127 40.792534 1.0 \n",
"3 2.40 -73.996017 40.738476 1.0 \n",
"4 5.65 -73.976395 40.739620 1.0 \n",
"5 0.70 -73.975975 40.761230 1.0 \n",
"\n",
" store_and_fwd_flag dropoff_longitude ... payment_type fare_amount \\\n",
"1 N -73.988052 ... 1.0 26.5 \n",
"2 N -73.952820 ... 1.0 5.5 \n",
"3 N -73.971405 ... 1.0 12.5 \n",
"4 N -73.950279 ... 1.0 22.0 \n",
"5 N -73.979774 ... 1.0 6.0 \n",
"\n",
" extra mta_tax tip_amount tolls_amount improvement_surcharge \\\n",
"1 1.0 0.5 5.50 0.0 0.3 \n",
"2 0.0 0.5 1.85 0.0 0.3 \n",
"3 0.0 0.5 2.66 0.0 0.3 \n",
"4 0.0 0.5 4.40 0.0 0.3 \n",
"5 0.0 0.5 1.70 0.0 0.3 \n",
"\n",
" total_amount PRIMARY_KEY foo \n",
"1 33.80 0-0-4 bar \n",
"2 8.15 0-0-9 bar \n",
"3 15.96 0-0-14 bar \n",
"4 27.20 0-0-19 bar \n",
"5 8.50 0-0-24 bar \n",
"\n",
"[5 rows x 21 columns]"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"R_output.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Convert the dataframe to Spark dataframe"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"root\n",
" |-- vendorid: double (nullable = true)\n",
" |-- tpep_pickup_datetime: double (nullable = true)\n",
" |-- tpep_dropoff_datetime: double (nullable = true)\n",
" |-- passenger_count: double (nullable = true)\n",
" |-- trip_distance: double (nullable = true)\n",
" |-- pickup_longitude: double (nullable = true)\n",
" |-- pickup_latitude: double (nullable = true)\n",
" |-- ratecodeid: double (nullable = true)\n",
" |-- store_and_fwd_flag: string (nullable = true)\n",
" |-- dropoff_longitude: double (nullable = true)\n",
" |-- dropoff_latitude: double (nullable = true)\n",
" |-- payment_type: double (nullable = true)\n",
" |-- fare_amount: double (nullable = true)\n",
" |-- extra: double (nullable = true)\n",
" |-- mta_tax: double (nullable = true)\n",
" |-- tip_amount: double (nullable = true)\n",
" |-- tolls_amount: double (nullable = true)\n",
" |-- improvement_surcharge: double (nullable = true)\n",
" |-- total_amount: double (nullable = true)\n",
" |-- PRIMARY_KEY: string (nullable = true)\n",
" |-- foo: string (nullable = true)\n",
"\n"
]
}
],
"source": [
"spark_df2 = sqlContext.createDataFrame(R_output)\n",
"spark_df2.printSchema()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Write it back as a dataset to Hive"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"spark_df2.write.mode('Overwrite').saveAsTable('default.updated_dataset')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ingest the new dataset back into BDD"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from subprocess import call\n",
"call([\"/u01/bdd/v1.2.0/BDD-1.2.0.31.813/dataprocessing/edp_cli/data_processing_CLI\",\"--table default.updated_dataset\"])"
]
}
],
"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.11"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment