Skip to content

Commit 608f0d4

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 1b39371 + 200aeb0 commit 608f0d4

35 files changed

+1809
-721
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ matrix:
1919
- python: 3.3
2020
env: UPDATE_ENV="conda remove netCDF4"
2121
- python: 3.4
22-
env: UPDATE_ENV="conda install -c pandas bottleneck h5py cython dask matplotlib && pip install cyordereddict h5netcdf"
22+
env: UPDATE_ENV="conda install -c pandas bottleneck h5py cython dask matplotlib seaborn && pip install cyordereddict h5netcdf"
2323
# don't require pydap tests to pass because the dap test server is unreliable
2424
- python: 2.7
2525
env: UPDATE_ENV="pip install pydap"

README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,5 +115,5 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
115115
See the License for the specific language governing permissions and
116116
limitations under the License.
117117

118-
xray includes portions of pandas and numpy. Their licenses are included in the
119-
licenses directory.
118+
xray includes portions of pandas, NumPy and Seaborn. Their licenses are
119+
included in the licenses directory.

doc/api-hidden.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,14 @@
2727
Dataset.count
2828
Dataset.dropna
2929
Dataset.fillna
30+
Dataset.where
3031

3132
core.groupby.DatasetGroupBy.assign
3233
core.groupby.DatasetGroupBy.assign_coords
3334
core.groupby.DatasetGroupBy.first
3435
core.groupby.DatasetGroupBy.last
3536
core.groupby.DatasetGroupBy.fillna
37+
core.groupby.DatasetGroupBy.where
3638

3739
Dataset.argsort
3840
Dataset.clip
@@ -66,11 +68,13 @@
6668
DataArray.count
6769
DataArray.dropna
6870
DataArray.fillna
71+
DataArray.where
6972

7073
core.groupby.DataArrayGroupBy.assign_coords
7174
core.groupby.DataArrayGroupBy.first
7275
core.groupby.DataArrayGroupBy.last
7376
core.groupby.DataArrayGroupBy.fillna
77+
core.groupby.DataArrayGroupBy.where
7478

7579
DataArray.argsort
7680
DataArray.clip

doc/api.rst

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ Indexing
9393
Dataset.loc
9494
Dataset.isel
9595
Dataset.sel
96+
Dataset.isel_points
97+
Dataset.sel_points
9698
Dataset.squeeze
9799
Dataset.reindex
98100
Dataset.reindex_like
@@ -129,6 +131,7 @@ Computation
129131
:py:attr:`~Dataset.count`
130132
:py:attr:`~Dataset.dropna`
131133
:py:attr:`~Dataset.fillna`
134+
:py:attr:`~Dataset.where`
132135

133136
**ndarray methods**:
134137
:py:attr:`~Dataset.argsort`
@@ -144,6 +147,7 @@ Computation
144147
:py:attr:`~core.groupby.DatasetGroupBy.first`
145148
:py:attr:`~core.groupby.DatasetGroupBy.last`
146149
:py:attr:`~core.groupby.DatasetGroupBy.fillna`
150+
:py:attr:`~core.groupby.DatasetGroupBy.where`
147151

148152
DataArray
149153
=========
@@ -202,6 +206,8 @@ Indexing
202206
DataArray.loc
203207
DataArray.isel
204208
DataArray.sel
209+
DataArray.isel_points
210+
DataArray.sel_points
205211
DataArray.squeeze
206212
DataArray.reindex
207213
DataArray.reindex_like
@@ -238,6 +244,7 @@ Computation
238244
:py:attr:`~DataArray.count`
239245
:py:attr:`~DataArray.dropna`
240246
:py:attr:`~DataArray.fillna`
247+
:py:attr:`~DataArray.where`
241248

242249
**ndarray methods**:
243250
:py:attr:`~DataArray.argsort`
@@ -253,6 +260,7 @@ Computation
253260
:py:attr:`~core.groupby.DataArrayGroupBy.first`
254261
:py:attr:`~core.groupby.DataArrayGroupBy.last`
255262
:py:attr:`~core.groupby.DataArrayGroupBy.fillna`
263+
:py:attr:`~core.groupby.DataArrayGroupBy.where`
256264

257265
Comparisons
258266
-----------
@@ -393,10 +401,10 @@ Plotting
393401
.. autosummary::
394402
:toctree: generated/
395403

396-
DataArray.plot
397-
DataArray.plot_contourf
398-
DataArray.plot_contour
399-
DataArray.plot_hist
400-
DataArray.plot_imshow
401-
DataArray.plot_line
402-
DataArray.plot_pcolormesh
404+
plot.plot
405+
plot.contourf
406+
plot.contour
407+
plot.hist
408+
plot.imshow
409+
plot.line
410+
plot.pcolormesh

doc/conf.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
print "no pandas"
3535
try:
3636
import matplotlib
37+
matplotlib.use('Agg')
3738
print "matplotlib: %s, %s" % (matplotlib.__version__, matplotlib.__file__)
3839
except ImportError:
3940
print "no matplotlib"
@@ -42,6 +43,11 @@
4243
print "ipython: %s, %s" % (IPython.__version__, IPython.__file__)
4344
except ImportError:
4445
print "no ipython"
46+
try:
47+
import seaborn
48+
print "seaborn: %s, %s" % (seaborn.__version__, seaborn.__file__)
49+
except ImportError:
50+
print "no seaborn"
4551

4652
# If extensions (or modules to document with autodoc) are in another directory,
4753
# add these directories to sys.path here. If the directory is relative to the

doc/examples/atlantic_noise.png

8.11 KB
Loading

doc/examples/cartopy_atlantic.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@
55

66
nlat = 15
77
nlon = 5
8-
atlantic = xray.DataArray(np.random.randn(nlat, nlon),
8+
arr = np.random.randn(nlat, nlon)
9+
arr[0, 0] = np.nan
10+
atlantic = xray.DataArray(arr,
911
coords = (np.linspace(50, 20, nlat), np.linspace(-60, -20, nlon)),
1012
dims = ('latitude', 'longitude'))
1113

12-
ax = plt.axes(projection=ccrs.PlateCarree())
14+
ax = plt.axes(projection=ccrs.Orthographic(-50, 30))
1315

14-
atlantic.plot(ax=ax)
16+
atlantic.plot(ax=ax, origin='upper', aspect='equal',
17+
transform=ccrs.PlateCarree())
1518

16-
ax.set_ylim(0, 90)
17-
ax.set_xlim(-180, 30)
19+
ax.set_global()
1820
ax.coastlines()
1921

2022
plt.savefig('atlantic_noise.png')

doc/indexing.rst

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ DataArray:
5757

5858
Positional indexing deviates from the NumPy when indexing with multiple
5959
arrays like ``arr[[0, 1], [0, 1]]``, as described in :ref:`indexing details`.
60+
See :ref:`pointwise indexing` for how to achieve this functionality in xray.
6061

6162
xray also supports label-based indexing, just like pandas. Because
6263
we use a :py:class:`pandas.Index` under the hood, label based indexing is very
@@ -122,7 +123,8 @@ __ http://legacy.python.org/dev/peps/pep-0472/
122123

123124
.. warning::
124125

125-
Do not try to assign values when using ``isel`` or ``sel``::
126+
Do not try to assign values when using any of the indexing methods ``isel``,
127+
``isel_points``, ``sel`` or ``sel_points``::
126128

127129
# DO NOT do this
128130
arr.isel(space=0) = 0
@@ -134,6 +136,35 @@ __ http://legacy.python.org/dev/peps/pep-0472/
134136
# this is safe
135137
arr[dict(space=0)] = 0
136138

139+
.. _pointwise indexing:
140+
141+
Pointwise indexing
142+
------------------
143+
144+
xray pointwise indexing supports the indexing along multiple labeled dimensions
145+
using list-like objects. While :py:meth:`~xray.DataArray.isel` performs
146+
orthogonal indexing, the :py:meth:`~xray.DataArray.isel_points` method
147+
provides similar numpy indexing behavior as if you were using multiple
148+
lists to index an array (e.g. ``arr[[0, 1], [0, 1]]`` ):
149+
150+
.. ipython:: python
151+
152+
# index by integer array indices
153+
da = xray.DataArray(np.arange(56).reshape((7, 8)), dims=['x', 'y'])
154+
da
155+
da.isel_points(x=[0, 1, 6], y=[0, 1, 0])
156+
157+
There is also :py:meth:`~xray.DataArray.sel_points`, which analogously
158+
allows you to do point-wise indexing by label:
159+
160+
.. ipython:: python
161+
162+
times = pd.to_datetime(['2000-01-03', '2000-01-02', '2000-01-01'])
163+
arr.sel_points(space=['IA', 'IL', 'IN'], time=times)
164+
165+
The equivalent pandas method to ``sel_points`` is
166+
:py:meth:`~pandas.DataFrame.lookup`.
167+
137168
Dataset indexing
138169
----------------
139170

@@ -145,13 +176,16 @@ simultaneously, returning a new dataset:
145176
ds = arr.to_dataset()
146177
ds.isel(space=[0], time=[0])
147178
ds.sel(time='2000-01-01')
179+
ds2 = da.to_dataset()
180+
ds2.isel_points(x=[0, 1, 6], y=[0, 1, 0], dim='points')
148181
149182
Positional indexing on a dataset is not supported because the ordering of
150183
dimensions in a dataset is somewhat ambiguous (it can vary between different
151184
arrays). However, you can do normal indexing with labeled dimensions:
152185

153186
.. ipython:: python
154187
188+
155189
ds[dict(space=[0], time=[0])]
156190
ds.loc[dict(time='2000-01-01')]
157191
@@ -338,3 +372,33 @@ Indexing axes with monotonic decreasing labels also works, as long as the
338372
339373
reversed_data = data[::-1]
340374
reversed_data.loc[3.1:0.9]
375+
376+
Masking with ``where``
377+
----------------------
378+
379+
Indexing methods on xray objects generally return a subset of the original data.
380+
However, it is sometimes useful to select an object with the same shape as the
381+
original data, but with some elements masked. To do this type of selection in
382+
xray, use :py:meth:`~xray.DataArray.where`:
383+
384+
.. ipython:: python
385+
386+
arr = xray.DataArray(np.arange(16).reshape(4, 4), dims=['x', 'y'])
387+
arr.where(arr.x + arr.y < 4)
388+
389+
This is particularly useful for ragged indexing of multi-dimensional data,
390+
e.g., to apply a 2D mask to an image. Note that ``where`` follows all the
391+
usual xray broadcasting and alignment rules for binary operations (e.g.,
392+
``+``) between the object being indexed and the condition, as described in
393+
:ref:`comput`:
394+
395+
.. ipython:: python
396+
397+
arr.where(arr.y < 2)
398+
399+
Multi-dimensional indexing
400+
--------------------------
401+
402+
Xray does not yet support efficient routines for generalized multi-dimensional
403+
indexing or regridding. However, we are definitely interested in adding support
404+
for this in the future (see :issue:`475` for the ongoing discussion).

0 commit comments

Comments
 (0)