686 lines
22 KiB
Plaintext
Executable File
686 lines
22 KiB
Plaintext
Executable File
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"<h1>10. NetCDF I/O</h1>\n",
|
|
"<h2>10/25/2023</h2>\n",
|
|
"\n",
|
|
"<h2>10.0 Last Time...</h2>\n",
|
|
"<ul>\n",
|
|
" <li>Statistics that are not resistant to outliers include the mean, the standard deviation, skewness, and kurtosis.</li>\n",
|
|
" <li>Statistics that are resistant to outliers include the median and the interquartile range.</li>\n",
|
|
" <li>By making use of dictionaries, we can create versatile, non-hard-coded programs!</li>\n",
|
|
" <li>glob is a package that enables us to grab all files within a directory</li>\n",
|
|
"</ul>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"<h2>10.1 Structure of a NetCDF File</h2>\n",
|
|
"\n",
|
|
"NetCDF is a commonly used file format in our field because it enables the storage of data as well as the storage of its <b>metadata</b>. Every major language in our field is equipped to deal with NetCDF files, and Python is no exception!\n",
|
|
"\n",
|
|
"There are <b>four</b> parameter types in a netCDF file:\n",
|
|
"<ul>\n",
|
|
" <li><b>Global attributes:</b> strings that describe the file as a whole: for example, a title, who created it, what standards it follows.</li>\n",
|
|
" <li><b>Variables:</b> entities that hold data, which includes the data, the domain the data is defined on (dimensionality), and metadata about the data (for example, units).</li>\n",
|
|
" <li><b>Variable attributes:</b> actual storage of the data's metadata.</li>\n",
|
|
" <li><b>Dimensions:</b> not only define the domain, but also might have values of their own (for example, latitude values, longitude values, altitude values, etc.).</li>\n",
|
|
"</ul>\n",
|
|
"\n",
|
|
"As an example, you might have a timeseries of surface temperature for a latitude-longitude grid. The dimensions for that dataset would be <b>lat</b>, <b>lon</b>, and <b>time</b>. The variable <b>lat</b> would just tell you the number of elements in the <b>lat</b> dimension</b>; likewise for <b>lon</b> and <b>time</b>. Finally, you might have a variable containing temperatures called <b>Ts</b> that would be 3-D, with dimensions of <b>lat</b>, <b>lon</b>, and <b>time</b>.\n",
|
|
"\n",
|
|
"There are several packages that can read NetCDF files; we're going to learn SciPy today - it's not necessarily the best, but it is one of the easiest to learn, and SciPy is a useful package for many other reasons."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"<h2>10.2 Reading a NetCDF File</h2>\n",
|
|
"\n",
|
|
"For NetCDF files, we're interested in the I/O functionality of SciPy, so we'll call that part of the package and assign it to an alias."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Import the I/O functionality of SciPy.\n",
|
|
"import numpy as np\n",
|
|
"import scipy.io as S\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"To create a file object, it's actually a pretty similar approach to what we did in our I/O lecture."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"<scipy.io._netcdf.netcdf_file object at 0x7f1a0448e4d0>\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Read in the provided NetCDF file in read-only mode.\n",
|
|
"fileobj = S.netcdf_file(\"../datasets/air.mon.mean.nc\", mode=\"r\")\n",
|
|
"print(fileobj)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"NetCDF file objects have several <b>attributes</b> that we can call on (more on this when we explore object-oriented programming). One of those attributes is called <b>variables</b>, which is a dictionary. The keys of the dictionary are strings corresponding to the names of the variables, and the values are a special kind of object called <b>variable objects</b> that contain the variable's values as well as any metadata (units, etc.).\n",
|
|
"\n",
|
|
"Another NetCDF file object attribute is <b>dimensions</b>, which is another dictionary. The keys of this dictionary are strings that are the names of the dimensions, and the values are the lengths of the dimensions.\n",
|
|
"\n",
|
|
"Let's see an example from our .nc file: a grid of monthly-mean temperature values."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"b'Monthly mean air temperature NCEP Reanalysis'\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Let's import NumPy and SciPy's I/O functionality.\n",
|
|
"fileobj = S.netcdf_file(\"../datasets/air.mon.mean.nc\", mode=\"r\")\n",
|
|
"\n",
|
|
"\n",
|
|
"# Now, create a file object!\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"# First, let's find out what information's in the title.\n",
|
|
"print(fileobj.title)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"{'lon': 144, 'lat': 73, 'time': None}\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Now let's explore the dimensions dictionary.\n",
|
|
"print(fileobj.dimensions)\n",
|
|
"\n",
|
|
"# Time is set to 'None' because that's this file's\n",
|
|
"# 'unlimited' dimension; you can keep adding new times to it\n",
|
|
"# and it will use the same lat/lon grid."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"{'lat': <scipy.io._netcdf.netcdf_variable object at 0x7f19fffc28d0>, 'lon': <scipy.io._netcdf.netcdf_variable object at 0x7f19fffc3450>, 'time': <scipy.io._netcdf.netcdf_variable object at 0x7f19fffc1f50>, 'air': <scipy.io._netcdf.netcdf_variable object at 0x7f19fffc1bd0>}\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# And let's see what kinds of variables are inside.\n",
|
|
"print(fileobj.variables)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"<scipy.io._netcdf.netcdf_variable object at 0x7f19fffc1bd0>\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Okay, that's all very messy!\n",
|
|
"# Now it's time to grab the values of air temperature.\n",
|
|
"\n",
|
|
"temp = fileobj.variables[\"air\"]\n",
|
|
"print(temp)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"b'degC'\n",
|
|
"(755, 73, 144)\n",
|
|
"[[[-34.926773 -34.926773 -34.926773 ... -34.926773 -34.926773\n",
|
|
" -34.926773 ]\n",
|
|
" [-35.13935 -35.129673 -35.12742 ... -35.188705 -35.170002\n",
|
|
" -35.14935 ]\n",
|
|
" [-34.352573 -34.04226 -33.768707 ... -35.333866 -35.002903\n",
|
|
" -34.671288 ]\n",
|
|
" ...\n",
|
|
" [-16.525156 -16.404509 -16.284832 ... -16.795155 -16.737736\n",
|
|
" -16.643543 ]\n",
|
|
" [-16.190313 -16.202248 -16.21677 ... -16.132574 -16.161928\n",
|
|
" -16.178377 ]\n",
|
|
" [-17.697733 -17.697733 -17.697733 ... -17.697733 -17.697733\n",
|
|
" -17.697733 ]]\n",
|
|
"\n",
|
|
" [[-33.311375 -33.311375 -33.311375 ... -33.311375 -33.311375\n",
|
|
" -33.311375 ]\n",
|
|
" [-34.65034 -34.476204 -34.29689 ... -35.18448 -35.009308\n",
|
|
" -34.835514 ]\n",
|
|
" [-34.1031 -33.619995 -33.161373 ... -35.606552 -35.103443\n",
|
|
" -34.602757 ]\n",
|
|
" ...\n",
|
|
" [-34.338963 -34.21862 -34.08241 ... -34.359997 -34.42724\n",
|
|
" -34.418617 ]\n",
|
|
" [-33.795513 -33.896553 -33.977238 ... -33.41517 -33.56758\n",
|
|
" -33.690342 ]\n",
|
|
" [-32.942413 -32.942413 -32.942413 ... -32.942413 -32.942413\n",
|
|
" -32.942413 ]]\n",
|
|
"\n",
|
|
" [[-29.716127 -29.716127 -29.716127 ... -29.716127 -29.716127\n",
|
|
" -29.716127 ]\n",
|
|
" [-29.4471 -29.499353 -29.551613 ... -29.365162 -29.385166\n",
|
|
" -29.41258 ]\n",
|
|
" [-28.544516 -28.366776 -28.227749 ... -29.282906 -29.01323\n",
|
|
" -28.763546 ]\n",
|
|
" ...\n",
|
|
" [-51.964516 -52.206455 -52.362263 ... -50.628704 -51.18032\n",
|
|
" -51.631298 ]\n",
|
|
" [-52.846123 -53.07613 -53.290974 ... -52.069355 -52.344517\n",
|
|
" -52.60097 ]\n",
|
|
" [-54.835476 -54.835476 -54.835476 ... -54.835476 -54.835476\n",
|
|
" -54.835476 ]]\n",
|
|
"\n",
|
|
" ...\n",
|
|
"\n",
|
|
" [[ -6.84033 -6.84033 -6.84033 ... -6.84033 -6.84033\n",
|
|
" -6.84033 ]\n",
|
|
" [ -8.222664 -8.076328 -7.9316626 ... -8.658329 -8.517663\n",
|
|
" -8.366997 ]\n",
|
|
" [ -8.124661 -7.610333 -7.1173277 ... -9.681327 -9.180997\n",
|
|
" -8.653992 ]\n",
|
|
" ...\n",
|
|
" [-54.956 -55.16667 -55.29166 ... -53.67867 -54.22433\n",
|
|
" -54.649338 ]\n",
|
|
" [-55.466324 -55.73534 -55.975994 ... -54.453335 -54.82867\n",
|
|
" -55.16467 ]\n",
|
|
" [-53.225002 -53.225002 -53.225002 ... -53.225002 -53.225002\n",
|
|
" -53.225002 ]]\n",
|
|
"\n",
|
|
" [[-16.640314 -16.640314 -16.640314 ... -16.640314 -16.640314\n",
|
|
" -16.640314 ]\n",
|
|
" [-20.58 -20.478704 -20.383224 ... -20.846767 -20.765804\n",
|
|
" -20.679348 ]\n",
|
|
" [-21.077736 -20.571283 -20.056448 ... -22.434835 -22.024187\n",
|
|
" -21.567738 ]\n",
|
|
" ...\n",
|
|
" [-44.52612 -44.629353 -44.69258 ... -43.85613 -44.15871\n",
|
|
" -44.375164 ]\n",
|
|
" [-44.219357 -44.39742 -44.56355 ... -43.50774 -43.770008\n",
|
|
" -44.004192 ]\n",
|
|
" [-41.401936 -41.401936 -41.401936 ... -41.401936 -41.401936\n",
|
|
" -41.401936 ]]\n",
|
|
"\n",
|
|
" [[-26.217333 -26.217333 -26.217333 ... -26.217333 -26.217333\n",
|
|
" -26.217333 ]\n",
|
|
" [-30.25533 -30.281328 -30.300997 ... -30.091661 -30.157658\n",
|
|
" -30.210995 ]\n",
|
|
" [-31.590332 -31.514662 -31.380667 ... -31.483662 -31.579662\n",
|
|
" -31.618664 ]\n",
|
|
" ...\n",
|
|
" [-32.93566 -32.809 -32.665333 ... -33.02433 -33.059994\n",
|
|
" -33.024666 ]\n",
|
|
" [-34.10533 -34.120663 -34.118332 ... -33.930668 -34.01266\n",
|
|
" -34.066994 ]\n",
|
|
" [-33.181664 -33.181664 -33.181664 ... -33.181664 -33.181664\n",
|
|
" -33.181664 ]]]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# We can now examine this data more carefully.\n",
|
|
"print(temp.units)\n",
|
|
"print(temp.shape)\n",
|
|
"print(temp[:])\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"-34.926773\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Let's be a little more restrained... how about all the data at the first lat/lon pair?\n",
|
|
"print(temp[0,0,0])\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"90.0\n",
|
|
"0.0\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# That seems pretty chilly! What are the lat/lon values?\n",
|
|
"lat = fileobj.variables[\"lat\"]\n",
|
|
"lon = fileobj.variables[\"lon\"]\n",
|
|
"\n",
|
|
"print(lat[0])\n",
|
|
"print(lon[0])\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Okay, that's reasonable for the North Pole.\n",
|
|
"# This grid is 2.5 degrees... let's find out what Seattle's weather was like!\n",
|
|
"\n",
|
|
"# Seattle is at approximately 47.5 N and 122.5 W.\n",
|
|
"\n",
|
|
"# This dataset's lon starts at 0 and counts up to 360.\n",
|
|
"# So 122.25 W corresponds to 360-122.5 = 237.5.\n",
|
|
"\n",
|
|
"# Remember, lat and lon are those weird data types:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[ 90. 87.5 85. 82.5 80. 77.5 75. 72.5 70. 67.5 65. 62.5\n",
|
|
" 60. 57.5 55. 52.5 50. 47.5 45. 42.5 40. 37.5 35. 32.5\n",
|
|
" 30. 27.5 25. 22.5 20. 17.5 15. 12.5 10. 7.5 5. 2.5\n",
|
|
" 0. -2.5 -5. -7.5 -10. -12.5 -15. -17.5 -20. -22.5 -25. -27.5\n",
|
|
" -30. -32.5 -35. -37.5 -40. -42.5 -45. -47.5 -50. -52.5 -55. -57.5\n",
|
|
" -60. -62.5 -65. -67.5 -70. -72.5 -75. -77.5 -80. -82.5 -85. -87.5\n",
|
|
" -90. ]\n",
|
|
"[ 0. 2.5 5. 7.5 10. 12.5 15. 17.5 20. 22.5 25. 27.5\n",
|
|
" 30. 32.5 35. 37.5 40. 42.5 45. 47.5 50. 52.5 55. 57.5\n",
|
|
" 60. 62.5 65. 67.5 70. 72.5 75. 77.5 80. 82.5 85. 87.5\n",
|
|
" 90. 92.5 95. 97.5 100. 102.5 105. 107.5 110. 112.5 115. 117.5\n",
|
|
" 120. 122.5 125. 127.5 130. 132.5 135. 137.5 140. 142.5 145. 147.5\n",
|
|
" 150. 152.5 155. 157.5 160. 162.5 165. 167.5 170. 172.5 175. 177.5\n",
|
|
" 180. 182.5 185. 187.5 190. 192.5 195. 197.5 200. 202.5 205. 207.5\n",
|
|
" 210. 212.5 215. 217.5 220. 222.5 225. 227.5 230. 232.5 235. 237.5\n",
|
|
" 240. 242.5 245. 247.5 250. 252.5 255. 257.5 260. 262.5 265. 267.5\n",
|
|
" 270. 272.5 275. 277.5 280. 282.5 285. 287.5 290. 292.5 295. 297.5\n",
|
|
" 300. 302.5 305. 307.5 310. 312.5 315. 317.5 320. 322.5 325. 327.5\n",
|
|
" 330. 332.5 335. 337.5 340. 342.5 345. 347.5 350. 352.5 355. 357.5]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# So let's save their values instead.\n",
|
|
"a = lat[:]\n",
|
|
"b = lon[:]\n",
|
|
"print(a)\n",
|
|
"print(b)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 17,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"(array([17]),)\n",
|
|
"(array([95]),)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Now we can use np.where() to find the locations of the values in the dataset.\n",
|
|
"sealat = np.where(a == 47.5)\n",
|
|
"sealon = np.where(b == 237.5)\n",
|
|
"\n",
|
|
"print(sealat)\n",
|
|
"print(sealon)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[[1.5006493]]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Let's print it out!\n",
|
|
"print(temp[0,sealat, sealon])\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 19,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"b'Monthly Mean Air Temperature'\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# If you want the full name of a particular variable, long_name is useful!\n",
|
|
"print(fileobj.variables[\"air\"].long_name)\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"<h2>10.3 Writing a NetCDF File</h2>\n",
|
|
"\n",
|
|
"Just as with normal files, we can write our own NetCDF files!\n",
|
|
"\n",
|
|
"You can create a NetCDF file object in write mode!"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 21,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[[ 0. 0.09983342 0.19866933 0.29552021 0.38941834 0.47942554\n",
|
|
" 0.56464247 0.64421769 0.71735609 0.78332691 0.84147098 0.89120736\n",
|
|
" 0.93203909 0.96355819 0.98544973 0.99749499 0.9995736 0.99166481\n",
|
|
" 0.97384763 0.94630009]\n",
|
|
" [ 0.90929743 0.86320937 0.8084964 0.74570521 0.67546318 0.59847214\n",
|
|
" 0.51550137 0.42737988 0.33498815 0.23924933 0.14112001 0.04158066\n",
|
|
" -0.05837414 -0.15774569 -0.2555411 -0.35078323 -0.44252044 -0.52983614\n",
|
|
" -0.61185789 -0.68776616]\n",
|
|
" [-0.7568025 -0.81827711 -0.87157577 -0.91616594 -0.95160207 -0.97753012\n",
|
|
" -0.993691 -0.99992326 -0.99616461 -0.98245261 -0.95892427 -0.92581468\n",
|
|
" -0.88345466 -0.83226744 -0.77276449 -0.70554033 -0.63126664 -0.55068554\n",
|
|
" -0.46460218 -0.37387666]\n",
|
|
" [-0.2794155 -0.1821625 -0.0830894 0.0168139 0.1165492 0.21511999\n",
|
|
" 0.31154136 0.40484992 0.49411335 0.57843976 0.6569866 0.72896904\n",
|
|
" 0.79366786 0.85043662 0.8987081 0.93799998 0.96791967 0.98816823\n",
|
|
" 0.99854335 0.99894134]\n",
|
|
" [ 0.98935825 0.96988981 0.94073056 0.90217183 0.85459891 0.79848711\n",
|
|
" 0.7343971 0.66296923 0.58491719 0.50102086 0.41211849 0.31909836\n",
|
|
" 0.22288991 0.12445442 0.02477543 -0.07515112 -0.17432678 -0.27176063\n",
|
|
" -0.36647913 -0.45753589]\n",
|
|
" [-0.54402111 -0.62507065 -0.69987469 -0.76768581 -0.82782647 -0.87969576\n",
|
|
" -0.92277542 -0.95663502 -0.98093623 -0.99543625 -0.99999021 -0.99455259\n",
|
|
" -0.97917773 -0.95401925 -0.91932853 -0.87545217 -0.82282859 -0.76198358\n",
|
|
" -0.69352508 -0.61813711]\n",
|
|
" [-0.53657292 -0.44964746 -0.35822928 -0.26323179 -0.16560418 -0.0663219\n",
|
|
" 0.03362305 0.13323204 0.23150983 0.32747444 0.42016704 0.50866146\n",
|
|
" 0.59207351 0.66956976 0.74037589 0.80378443 0.85916181 0.90595474\n",
|
|
" 0.94369567 0.9720075 ]\n",
|
|
" [ 0.99060736 0.99930939 0.99802665 0.98677196 0.96565778 0.93489506\n",
|
|
" 0.89479117 0.84574683 0.78825207 0.72288135 0.65028784 0.57119687\n",
|
|
" 0.48639869 0.39674057 0.30311836 0.20646748 0.10775365 0.00796318\n",
|
|
" -0.09190685 -0.19085858]\n",
|
|
" [-0.28790332 -0.38207142 -0.47242199 -0.55805227 -0.63810668 -0.71178534\n",
|
|
" -0.77835208 -0.83714178 -0.88756703 -0.92912401 -0.96139749 -0.98406501\n",
|
|
" -0.99690007 -0.99977443 -0.99265938 -0.97562601 -0.9488445 -0.91258245\n",
|
|
" -0.86720218 -0.81315711]\n",
|
|
" [-0.75098725 -0.68131377 -0.60483282 -0.52230859 -0.43456562 -0.34248062\n",
|
|
" -0.24697366 -0.14899903 -0.04953564 0.05042269 0.14987721 0.24783421\n",
|
|
" 0.34331493 0.43536536 0.52306577 0.60553987 0.68196362 0.75157342\n",
|
|
" 0.81367374 0.8676441 ]]\n",
|
|
"42.0\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"newfile = S.netcdf_file(\"new.nc\",mode=\"w\")\n",
|
|
"\n",
|
|
"# Let's start by putting in 10 latitude and 20 longitude values.\n",
|
|
"lat = np.arange(10)\n",
|
|
"lon = np.arange(10)\n",
|
|
"\n",
|
|
"# And maybe two different sets of data, one array and one scalar.\n",
|
|
"data1 = np.reshape(np.sin(np.arange(200)*0.1),(10,20))\n",
|
|
"data2 = 42.0\n",
|
|
"\n",
|
|
"print(data1)\n",
|
|
"print(data2)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 23,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# So far so good! Let's create the actual dimension information.\n",
|
|
"newfile.createDimension(\"lat\",len(lat))\n",
|
|
"newfile.createDimension(\"lon\",len(lon))\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Now the names of our variables!\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# And now we assign the actual values to our variables!\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# And assign some units!\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Add a title to finish up!\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Okay, so having done all that (don't worry if all the details are unclear - this is a fairly advanced topic that will take some practice!), let's try reading our values."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"<h2>10.4 NetCDF Example</h2>\n",
|
|
"\n",
|
|
"Let's pull up some monthly mean surface air temperature data from our air.mon.mean.nc data file. These data come from the NCEP/NCAR Reanalysis 1."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"\n",
|
|
"# Let's take a look at the time units.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Well, that seems confusing.\n",
|
|
"# Let's create a new version of the file where time just starts at 0.0, and change the units string so it just says 'hours'.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# And let's test it!\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"<h2>10.5 Take-Home Points</h2>\n",
|
|
"<ul>\n",
|
|
" <li>NetCDF is a powerful file type containing global attributes, variables, variable attributes, and dimensions.</li>\n",
|
|
" <li>We can read from NetCDF files using similar syntax to that for regular files.</li>\n",
|
|
" <li>Using attributes such as 'dimensions' and 'variables', we can learn about individual variables in the dataset.</li>\n",
|
|
" <li>We can also write to NetCDF files in a simlar way.</li>\n",
|
|
"</ul>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3 (ipykernel)",
|
|
"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.11.4"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
}
|