Skip to content

Instantly share code, notes, and snippets.

@ajelenak
Created April 18, 2019 16:29
Show Gist options
  • Save ajelenak/9e6ece729de0e4f59debd425cd205eab to your computer and use it in GitHub Desktop.
Save ajelenak/9e6ece729de0e4f59debd425cd205eab to your computer and use it in GitHub Desktop.
Exploring a DAS-HDF5 with xarray
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Working with DAS-HDF5 Data in xarray\n",
"\n",
"xarray: http://xarray.pydata.org\n",
"\n",
"In xarray, a _Dataset_ represents entire HDF5 file content. A _Dataset_ consists of one or more _DataArrays_ which are HDF5 datasets."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import xarray as xr"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The DAS-HDF5 file with PoroTomo distributed acoustic sensing data:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"ptomo = xr.open_dataset('../das2h5/PoroTomo/SEG-Y/porotomo-das.h5', engine='h5netcdf')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"How xarray understands the file's content:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<xarray.Dataset>\n",
"Dimensions: (channel: 8721, trace: 600000)\n",
"Coordinates:\n",
" * channel (channel) float64 -20.0 -19.0 -18.0 ... 8.698e+03 8.699e+03 8.7e+03\n",
" t (trace) datetime64[ns] ...\n",
" * trace (trace) float64 0.0 1.0 2.0 3.0 4.0 ... 6e+05 6e+05 6e+05 6e+05\n",
" x (channel) float32 ...\n",
" y (channel) float32 ...\n",
" z (channel) float32 ...\n",
"Data variables:\n",
" crs uint8 ...\n",
" das (trace, channel) float32 ...\n",
"Attributes:\n",
" Conventions: DAS-HDF5-1.0, CF-1.7, ACDD-1.3\n",
" creator_institution: Uni. Wisconsin\n",
" creator_name: Uni. Wisconsin\n",
" creator_type: institution\n",
" creator_url: https://gdr.openei.org/submissions/980\n",
" date_created: 2019-04-17T22:56:43Z\n",
" geospatial_lat_max: 39.81236443966049\n",
" geospatial_lat_min: 39.799012340286616\n",
" geospatial_lat_units: degree_north\n",
" geospatial_lon_max: -118.996167242865\n",
" geospatial_lon_min: -119.01132662008733\n",
" geospatial_lon_units: degree_east\n",
" instrument: iDAS S/N: iDAS16043\n",
" project: CoRDIAL\n",
" publisher_email: [email protected]\n",
" publisher_institution: Akadio Inc.\n",
" publisher_name: Akadio Inc.\n",
" publisher_type: institution\n",
" publisher_url: https://www.akadio.com\n",
" standard_name_vocabulary: CF Standard Names (v64, 5 March 2019)\n",
" time_coverage_end: 2016-03-26T00:20:15.132759Z\n",
" time_coverage_start: 2016-03-26T00:10:15.133759Z"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ptomo"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## DAS Data"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<xarray.DataArray 'das' (trace: 600000, channel: 8721)>\n",
"[5232600000 values with dtype=float32]\n",
"Coordinates:\n",
" * channel (channel) float64 -20.0 -19.0 -18.0 ... 8.698e+03 8.699e+03 8.7e+03\n",
" t (trace) datetime64[ns] ...\n",
" * trace (trace) float64 0.0 1.0 2.0 3.0 4.0 ... 6e+05 6e+05 6e+05 6e+05\n",
" x (channel) float32 ...\n",
" y (channel) float32 ...\n",
" z (channel) float32 ...\n",
"Attributes:\n",
" grid_mapping: crs\n",
" long_name: strain\n",
" sampling_interval_seconds: 0.001"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"das = ptomo['das']\n",
"das"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `das` HDF5 dataset is an xarray's DataArray. xarray provides additional features if HDF5 dimension scales are attached to one or more of the HDF5 dataset's dimensions. The attached HDF5 dimension scales are called _dimension coordinates_ in xarray.\n",
"\n",
"The dimension coordinates for `das` are:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"('trace', 'channel')"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"das.dims"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`/trace` and `/channel` are HDF5 dimension scales in the DAS-HDF5 file attached to the first and second `/das` HDF5 dataset dimensions, respectively.\n",
"\n",
"Additionally, xarray recognizes _non-dimension coordinates_ of a DataArray. These are HDF5 datasets that share the same HDF5 dimension scales (xarray dimension coordinates) with a particular DataArray."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Coordinates:\n",
" * channel (channel) float64 -20.0 -19.0 -18.0 ... 8.698e+03 8.699e+03 8.7e+03\n",
" t (trace) datetime64[ns] ...\n",
" * trace (trace) float64 0.0 1.0 2.0 3.0 4.0 ... 6e+05 6e+05 6e+05 6e+05\n",
" x (channel) float32 ...\n",
" y (channel) float32 ...\n",
" z (channel) float32 ..."
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"das.coords"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`/channel` and `/trace` have an `*` to their names which indicates they are recognized as the dimension coordinates of the `/das` DataArray. The `/t`, `/x`, `/y`, `/z` HDF5 datasets do not have an `*` next to their names but are grouped according to the shared HDF5 dimension scales (xarray dimension coordinates). This makes them non-dimension coordinates to the `/das` DataArray.\n",
"\n",
"xarray builds upon the pandas package so DataArray's dimension coordinates are also pandas indexes:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"channel: Float64Index([ -20.0, -19.0, -18.0, -17.0, -16.0, -15.0, -14.0, -13.0,\n",
" -12.0, -11.0,\n",
" ...\n",
" 8691.0, 8692.0, 8693.0, 8694.0, 8695.0, 8696.0, 8697.0, 8698.0,\n",
" 8699.0, 8700.0],\n",
" dtype='float64', name='channel', length=8721)\n",
"trace: Float64Index([ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0,\n",
" 6.0, 7.0, 8.0, 9.0,\n",
" ...\n",
" 599990.0, 599991.0, 599992.0, 599993.0, 599994.0, 599995.0,\n",
" 599996.0, 599997.0, 599998.0, 599999.0],\n",
" dtype='float64', name='trace', length=600000)"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"das.indexes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## xarray View of `/das` Dimension Coordinates"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<xarray.DataArray 'trace' (trace: 600000)>\n",
"array([0.00000e+00, 1.00000e+00, 2.00000e+00, ..., 5.99997e+05, 5.99998e+05,\n",
" 5.99999e+05])\n",
"Coordinates:\n",
" t (trace) datetime64[ns] ...\n",
" * trace (trace) float64 0.0 1.0 2.0 3.0 4.0 ... 6e+05 6e+05 6e+05 6e+05\n",
"Attributes:\n",
" long_name: trace number\n",
" valid_max: 599999\n",
" valid_min: 0"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"das.coords['trace']"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<xarray.DataArray 'channel' (channel: 8721)>\n",
"array([ -20., -19., -18., ..., 8698., 8699., 8700.])\n",
"Coordinates:\n",
" * channel (channel) float64 -20.0 -19.0 -18.0 ... 8.698e+03 8.699e+03 8.7e+03\n",
" x (channel) float32 ...\n",
" y (channel) float32 ...\n",
" z (channel) float32 ...\n",
"Attributes:\n",
" long_name: channel number\n",
" valid_max: 8700\n",
" valid_min: -20"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"das.coords['channel']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## xarray View of `/das` Non-Dimension Coordinates"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Temporal coordinate `/t`:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<xarray.DataArray 't' (trace: 600000)>\n",
"[600000 values with dtype=datetime64[ns]]\n",
"Coordinates:\n",
" t (trace) datetime64[ns] ...\n",
" * trace (trace) float64 0.0 1.0 2.0 3.0 4.0 ... 6e+05 6e+05 6e+05 6e+05\n",
"Attributes:\n",
" standard_name: time"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"das.coords['t']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Geospatial `/x` coordinate (UTM Easting):"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<xarray.DataArray 'x' (channel: 8721)>\n",
"array([nan, nan, nan, ..., nan, nan, nan], dtype=float32)\n",
"Coordinates:\n",
" * channel (channel) float64 -20.0 -19.0 -18.0 ... 8.698e+03 8.699e+03 8.7e+03\n",
" x (channel) float32 nan nan nan nan nan nan ... nan nan nan nan nan\n",
" y (channel) float32 ...\n",
" z (channel) float32 ...\n",
"Attributes:\n",
" long_name: Easting\n",
" standard_name: projection_x_coordinate\n",
" units: m\n",
" valid_max: 329136.0\n",
" valid_min: 327805.0"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"das.coords['x']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Geospatial `/y` coordinate (UTM Northing):"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<xarray.DataArray 'y' (channel: 8721)>\n",
"array([nan, nan, nan, ..., nan, nan, nan], dtype=float32)\n",
"Coordinates:\n",
" * channel (channel) float64 -20.0 -19.0 -18.0 ... 8.698e+03 8.699e+03 8.7e+03\n",
" x (channel) float32 nan nan nan nan nan nan ... nan nan nan nan nan\n",
" y (channel) float32 nan nan nan nan nan nan ... nan nan nan nan nan\n",
" z (channel) float32 ...\n",
"Attributes:\n",
" long_name: Northing\n",
" standard_name: projection_y_coordinate\n",
" units: m\n",
" valid_max: 4408838.0\n",
" valid_min: 4407385.0"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"das.coords['y']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Geospatial elevation `/z` coordinate:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<xarray.DataArray 'z' (channel: 8721)>\n",
"array([nan, nan, nan, ..., nan, nan, nan], dtype=float32)\n",
"Coordinates:\n",
" * channel (channel) float64 -20.0 -19.0 -18.0 ... 8.698e+03 8.699e+03 8.7e+03\n",
" x (channel) float32 nan nan nan nan nan nan ... nan nan nan nan nan\n",
" y (channel) float32 nan nan nan nan nan nan ... nan nan nan nan nan\n",
" z (channel) float32 nan nan nan nan nan nan ... nan nan nan nan nan\n",
"Attributes:\n",
" long_name: Elevation\n",
" standard_name: height_above_reference_ellipsoid\n",
" units: m\n",
" valid_max: 1262.0\n",
" valid_min: 1225.0"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"das.coords['z']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Subsetting `/das` Data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Subsetting `/das` data based on its dimension coordinates"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Standard NumPy array syntax:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<xarray.DataArray 'das' (trace: 3, channel: 5)>\n",
"array([[ 0.004491, -0.002341, -0.004233, -0.006993, -0.001236],\n",
" [ 0.004811, 0.003177, -0.000558, -0.002522, 0.000955],\n",
" [-0.000591, 0.001473, 0.001649, 0.003155, 0.001285]], dtype=float32)\n",
"Coordinates:\n",
" * channel (channel) float64 3.978e+03 3.979e+03 3.98e+03 3.981e+03 3.982e+03\n",
" t (trace) datetime64[ns] ...\n",
" * trace (trace) float64 3.457e+05 3.457e+05 3.457e+05\n",
" x (channel) float32 328830.34 328829.34 328828.34 328827.3 328826.3\n",
" y (channel) float32 4408566.5 4408566.5 4408567.0 4408567.0 4408567.0\n",
" z (channel) float32 1251.651 1251.624 1251.597 1251.569 1251.541\n",
"Attributes:\n",
" grid_mapping: crs\n",
" long_name: strain\n",
" sampling_interval_seconds: 0.001"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"das[345678:345681, 3998:4003]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Using dimension coordinate names (their order does not matter like in the above case):"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<xarray.DataArray 'das' (trace: 3, channel: 5)>\n",
"array([[ 0.004491, -0.002341, -0.004233, -0.006993, -0.001236],\n",
" [ 0.004811, 0.003177, -0.000558, -0.002522, 0.000955],\n",
" [-0.000591, 0.001473, 0.001649, 0.003155, 0.001285]], dtype=float32)\n",
"Coordinates:\n",
" * channel (channel) float64 3.978e+03 3.979e+03 3.98e+03 3.981e+03 3.982e+03\n",
" t (trace) datetime64[ns] ...\n",
" * trace (trace) float64 3.457e+05 3.457e+05 3.457e+05\n",
" x (channel) float32 328830.34 328829.34 328828.34 328827.3 328826.3\n",
" y (channel) float32 4408566.5 4408566.5 4408567.0 4408567.0 4408567.0\n",
" z (channel) float32 1251.651 1251.624 1251.597 1251.569 1251.541\n",
"Attributes:\n",
" grid_mapping: crs\n",
" long_name: strain\n",
" sampling_interval_seconds: 0.001"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"das.isel(channel=slice(3998, 4003), trace=slice(345678, 345681))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The above approach is much more expressive if the dimension coordinates represent physical quantities. While `/trace` could be replaced with a time coordinate, `/channel` cannot be replaced with either of geospatial `/x` and `/y` coordinates."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Subsetting `/das` data based on its non-dimension coordinates"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"pandas-like access to `/das` coordinates:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<xarray.DataArray 't' (trace: 600000)>\n",
"[600000 values with dtype=datetime64[ns]]\n",
"Coordinates:\n",
" t (trace) datetime64[ns] ...\n",
" * trace (trace) float64 0.0 1.0 2.0 3.0 4.0 ... 6e+05 6e+05 6e+05 6e+05\n",
"Attributes:\n",
" standard_name: time"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"das.t"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"pandas-style syntax still allows standard array subsetting:"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<xarray.DataArray 't' (trace: 4)>\n",
"array(['2016-03-26T00:10:15.133758976', '2016-03-26T00:10:15.134758912',\n",
" '2016-03-26T00:10:15.135759104', '2016-03-26T00:10:15.136759040'],\n",
" dtype='datetime64[ns]')\n",
"Coordinates:\n",
" t (trace) datetime64[ns] ...\n",
" * trace (trace) float64 0.0 1.0 2.0 3.0\n",
"Attributes:\n",
" standard_name: time"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"das.t[:4]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Subsetting with temporal non-dimension coordinate `/t`:"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<xarray.DataArray 'das' (trace: 1000, channel: 8721)>\n",
"[8721000 values with dtype=float32]\n",
"Coordinates:\n",
" * channel (channel) float64 -20.0 -19.0 -18.0 ... 8.698e+03 8.699e+03 8.7e+03\n",
" t (trace) datetime64[ns] 2016-03-26T00:18:15.000759040 ... 2016-03-26T00:18:15.999758848\n",
" * trace (trace) float64 4.799e+05 4.799e+05 ... 4.809e+05 4.809e+05\n",
" x (channel) float32 nan nan nan nan nan nan ... nan nan nan nan nan\n",
" y (channel) float32 nan nan nan nan nan nan ... nan nan nan nan nan\n",
" z (channel) float32 nan nan nan nan nan nan ... nan nan nan nan nan\n",
"Attributes:\n",
" grid_mapping: crs\n",
" long_name: strain\n",
" sampling_interval_seconds: 0.001"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"das.isel(trace=((das.t >= np.datetime64('2016-03-26T00:18:15')) & (das.t < np.datetime64('2016-03-26T00:18:16'))))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Subsetting with the UTM easting non-dimension coordinate `x`:"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<xarray.DataArray 'das' (trace: 600000, channel: 50)>\n",
"[30000000 values with dtype=float32]\n",
"Coordinates:\n",
" * channel (channel) float64 1.247e+03 1.248e+03 ... 1.295e+03 1.296e+03\n",
" t (trace) datetime64[ns] 2016-03-26T00:10:15.133758976 ... 2016-03-26T00:20:15.132759040\n",
" * trace (trace) float64 0.0 1.0 2.0 3.0 4.0 ... 6e+05 6e+05 6e+05 6e+05\n",
" x (channel) float32 328150.22 328151.22 ... 328198.72 328199.72\n",
" y (channel) float32 4407898.0 4407898.0 ... 4407899.0 4407899.0\n",
" z (channel) float32 1235.608 1235.643 1235.677 ... 1237.328 1237.368\n",
"Attributes:\n",
" grid_mapping: crs\n",
" long_name: strain\n",
" sampling_interval_seconds: 0.001"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"das.isel(channel=((das.x > 328150) & (das.x <= 328200)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Combining data subsetting with two non-dimension coordinates:"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<xarray.DataArray 'das' (trace: 1000, channel: 50)>\n",
"array([[-0.006819, -0.008367, -0.006011, ..., -0.004562, 0.004579, 0.00672 ],\n",
" [-0.003237, -0.003197, -0.003797, ..., -0.001981, 0.001947, 0.0024 ],\n",
" [-0.009104, -0.008303, -0.010787, ..., -0.005546, -0.000132, 0.001944],\n",
" ...,\n",
" [-0.007377, -0.006456, -0.004921, ..., -0.025731, -0.026785, -0.028987],\n",
" [-0.005419, -0.002689, 0.005684, ..., -0.018336, -0.019822, -0.023818],\n",
" [ 0.002168, 0.002383, 0.006397, ..., -0.014686, -0.018366, -0.021179]],\n",
" dtype=float32)\n",
"Coordinates:\n",
" * channel (channel) float64 1.247e+03 1.248e+03 ... 1.295e+03 1.296e+03\n",
" t (trace) datetime64[ns] 2016-03-26T00:18:15.000759040 ... 2016-03-26T00:18:15.999758848\n",
" * trace (trace) float64 4.799e+05 4.799e+05 ... 4.809e+05 4.809e+05\n",
" x (channel) float32 328150.22 328151.22 ... 328198.72 328199.72\n",
" y (channel) float32 4407898.0 4407898.0 ... 4407899.0 4407899.0\n",
" z (channel) float32 1235.608 1235.643 1235.677 ... 1237.328 1237.368\n",
"Attributes:\n",
" grid_mapping: crs\n",
" long_name: strain\n",
" sampling_interval_seconds: 0.001"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"das.isel(channel=((das.x > 328150) & (das.x <= 328200)),\n",
" trace=((das.t >= np.datetime64('2016-03-26T00:18:15')) & (das.t < np.datetime64('2016-03-26T00:18:16'))))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Based on the above examples, using 1D non-dimension coordinates to subset an xarray's DataArray is possible, albeit with somewhat cumbersome syntax. The user must know which dimension coordinate is associated with each non-dimension coordinate."
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"ptomo.close()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"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.6.8"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment