@@ -351,7 +351,144 @@ def test_dtype_coercion_error(self) -> None:
351
351
ds .to_netcdf (path , format = format )
352
352
353
353
354
- class DatasetIOBase :
354
+ class BackendIndexingTestsMixin :
355
+ def test_orthogonal_indexing (self ) -> None :
356
+ in_memory = create_test_data ()
357
+ with self .roundtrip (in_memory ) as on_disk :
358
+ indexers = {"dim1" : [1 , 2 , 0 ], "dim2" : [3 , 2 , 0 , 3 ], "dim3" : np .arange (5 )}
359
+ expected = in_memory .isel (indexers )
360
+ actual = on_disk .isel (** indexers )
361
+ # make sure the array is not yet loaded into memory
362
+ assert not actual ["var1" ].variable ._in_memory
363
+ assert_identical (expected , actual )
364
+ # do it twice, to make sure we're switched from orthogonal -> numpy
365
+ # when we cached the values
366
+ actual = on_disk .isel (** indexers )
367
+ assert_identical (expected , actual )
368
+
369
+ def test_vectorized_indexing (self ) -> None :
370
+ in_memory = create_test_data ()
371
+ with self .roundtrip (in_memory ) as on_disk :
372
+ indexers = {
373
+ "dim1" : DataArray ([0 , 2 , 0 ], dims = "a" ),
374
+ "dim2" : DataArray ([0 , 2 , 3 ], dims = "a" ),
375
+ }
376
+ expected = in_memory .isel (indexers )
377
+ actual = on_disk .isel (** indexers )
378
+ # make sure the array is not yet loaded into memory
379
+ assert not actual ["var1" ].variable ._in_memory
380
+ assert_identical (expected , actual .load ())
381
+ # do it twice, to make sure we're switched from
382
+ # vectorized -> numpy when we cached the values
383
+ actual = on_disk .isel (** indexers )
384
+ assert_identical (expected , actual )
385
+
386
+ def multiple_indexing (indexers ):
387
+ # make sure a sequence of lazy indexings certainly works.
388
+ with self .roundtrip (in_memory ) as on_disk :
389
+ actual = on_disk ["var3" ]
390
+ expected = in_memory ["var3" ]
391
+ for ind in indexers :
392
+ actual = actual .isel (ind )
393
+ expected = expected .isel (ind )
394
+ # make sure the array is not yet loaded into memory
395
+ assert not actual .variable ._in_memory
396
+ assert_identical (expected , actual .load ())
397
+
398
+ # two-staged vectorized-indexing
399
+ indexers2 = [
400
+ {
401
+ "dim1" : DataArray ([[0 , 7 ], [2 , 6 ], [3 , 5 ]], dims = ["a" , "b" ]),
402
+ "dim3" : DataArray ([[0 , 4 ], [1 , 3 ], [2 , 2 ]], dims = ["a" , "b" ]),
403
+ },
404
+ {"a" : DataArray ([0 , 1 ], dims = ["c" ]), "b" : DataArray ([0 , 1 ], dims = ["c" ])},
405
+ ]
406
+ multiple_indexing (indexers2 )
407
+
408
+ # vectorized-slice mixed
409
+ indexers3 = [
410
+ {
411
+ "dim1" : DataArray ([[0 , 7 ], [2 , 6 ], [3 , 5 ]], dims = ["a" , "b" ]),
412
+ "dim3" : slice (None , 10 ),
413
+ }
414
+ ]
415
+ multiple_indexing (indexers3 )
416
+
417
+ # vectorized-integer mixed
418
+ indexers4 = [
419
+ {"dim3" : 0 },
420
+ {"dim1" : DataArray ([[0 , 7 ], [2 , 6 ], [3 , 5 ]], dims = ["a" , "b" ])},
421
+ {"a" : slice (None , None , 2 )},
422
+ ]
423
+ multiple_indexing (indexers4 )
424
+
425
+ # vectorized-integer mixed
426
+ indexers5 = [
427
+ {"dim3" : 0 },
428
+ {"dim1" : DataArray ([[0 , 7 ], [2 , 6 ], [3 , 5 ]], dims = ["a" , "b" ])},
429
+ {"a" : 1 , "b" : 0 },
430
+ ]
431
+ multiple_indexing (indexers5 )
432
+
433
+ def test_vectorized_indexing_negative_step (self ) -> None :
434
+ # use dask explicitly when present
435
+ open_kwargs : dict [str , Any ] | None
436
+ if has_dask :
437
+ open_kwargs = {"chunks" : {}}
438
+ else :
439
+ open_kwargs = None
440
+ in_memory = create_test_data ()
441
+
442
+ def multiple_indexing (indexers ):
443
+ # make sure a sequence of lazy indexings certainly works.
444
+ with self .roundtrip (in_memory , open_kwargs = open_kwargs ) as on_disk :
445
+ actual = on_disk ["var3" ]
446
+ expected = in_memory ["var3" ]
447
+ for ind in indexers :
448
+ actual = actual .isel (ind )
449
+ expected = expected .isel (ind )
450
+ # make sure the array is not yet loaded into memory
451
+ assert not actual .variable ._in_memory
452
+ assert_identical (expected , actual .load ())
453
+
454
+ # with negative step slice.
455
+ indexers = [
456
+ {
457
+ "dim1" : DataArray ([[0 , 7 ], [2 , 6 ], [3 , 5 ]], dims = ["a" , "b" ]),
458
+ "dim3" : slice (- 1 , 1 , - 1 ),
459
+ }
460
+ ]
461
+ multiple_indexing (indexers )
462
+
463
+ # with negative step slice.
464
+ indexers = [
465
+ {
466
+ "dim1" : DataArray ([[0 , 7 ], [2 , 6 ], [3 , 5 ]], dims = ["a" , "b" ]),
467
+ "dim3" : slice (- 1 , 1 , - 2 ),
468
+ }
469
+ ]
470
+ multiple_indexing (indexers )
471
+
472
+ def test_outer_indexing_reversed (self ) -> None :
473
+ # regression test for GH6560
474
+ ds = xr .Dataset (
475
+ {"z" : (("t" , "p" , "y" , "x" ), np .ones ((1 , 1 , 31 , 40 )))},
476
+ )
477
+
478
+ with self .roundtrip (ds ) as on_disk :
479
+ subset = on_disk .isel (t = [0 ], p = 0 ).z [:, ::10 , ::10 ][:, ::- 1 , :]
480
+ assert subset .sizes == subset .load ().sizes
481
+
482
+ def test_isel_dataarray (self ) -> None :
483
+ # Make sure isel works lazily. GH:issue:1688
484
+ in_memory = create_test_data ()
485
+ with self .roundtrip (in_memory ) as on_disk :
486
+ expected = in_memory .isel (dim2 = in_memory ["dim2" ] < 3 )
487
+ actual = on_disk .isel (dim2 = on_disk ["dim2" ] < 3 )
488
+ assert_identical (expected , actual )
489
+
490
+
491
+ class DatasetIOBase (BackendIndexingTestsMixin ):
355
492
engine : T_NetcdfEngine | None = None
356
493
file_format : T_NetcdfTypes | None = None
357
494
@@ -695,141 +832,6 @@ def test_roundtrip_boolean_dtype(self) -> None:
695
832
assert_identical (original , actual2 )
696
833
assert actual2 ["x" ].dtype == "bool"
697
834
698
- def test_orthogonal_indexing (self ) -> None :
699
- in_memory = create_test_data ()
700
- with self .roundtrip (in_memory ) as on_disk :
701
- indexers = {"dim1" : [1 , 2 , 0 ], "dim2" : [3 , 2 , 0 , 3 ], "dim3" : np .arange (5 )}
702
- expected = in_memory .isel (indexers )
703
- actual = on_disk .isel (** indexers )
704
- # make sure the array is not yet loaded into memory
705
- assert not actual ["var1" ].variable ._in_memory
706
- assert_identical (expected , actual )
707
- # do it twice, to make sure we're switched from orthogonal -> numpy
708
- # when we cached the values
709
- actual = on_disk .isel (** indexers )
710
- assert_identical (expected , actual )
711
-
712
- def test_vectorized_indexing (self ) -> None :
713
- in_memory = create_test_data ()
714
- with self .roundtrip (in_memory ) as on_disk :
715
- indexers = {
716
- "dim1" : DataArray ([0 , 2 , 0 ], dims = "a" ),
717
- "dim2" : DataArray ([0 , 2 , 3 ], dims = "a" ),
718
- }
719
- expected = in_memory .isel (indexers )
720
- actual = on_disk .isel (** indexers )
721
- # make sure the array is not yet loaded into memory
722
- assert not actual ["var1" ].variable ._in_memory
723
- assert_identical (expected , actual .load ())
724
- # do it twice, to make sure we're switched from
725
- # vectorized -> numpy when we cached the values
726
- actual = on_disk .isel (** indexers )
727
- assert_identical (expected , actual )
728
-
729
- def multiple_indexing (indexers ):
730
- # make sure a sequence of lazy indexings certainly works.
731
- with self .roundtrip (in_memory ) as on_disk :
732
- actual = on_disk ["var3" ]
733
- expected = in_memory ["var3" ]
734
- for ind in indexers :
735
- actual = actual .isel (ind )
736
- expected = expected .isel (ind )
737
- # make sure the array is not yet loaded into memory
738
- assert not actual .variable ._in_memory
739
- assert_identical (expected , actual .load ())
740
-
741
- # two-staged vectorized-indexing
742
- indexers2 = [
743
- {
744
- "dim1" : DataArray ([[0 , 7 ], [2 , 6 ], [3 , 5 ]], dims = ["a" , "b" ]),
745
- "dim3" : DataArray ([[0 , 4 ], [1 , 3 ], [2 , 2 ]], dims = ["a" , "b" ]),
746
- },
747
- {"a" : DataArray ([0 , 1 ], dims = ["c" ]), "b" : DataArray ([0 , 1 ], dims = ["c" ])},
748
- ]
749
- multiple_indexing (indexers2 )
750
-
751
- # vectorized-slice mixed
752
- indexers3 = [
753
- {
754
- "dim1" : DataArray ([[0 , 7 ], [2 , 6 ], [3 , 5 ]], dims = ["a" , "b" ]),
755
- "dim3" : slice (None , 10 ),
756
- }
757
- ]
758
- multiple_indexing (indexers3 )
759
-
760
- # vectorized-integer mixed
761
- indexers4 = [
762
- {"dim3" : 0 },
763
- {"dim1" : DataArray ([[0 , 7 ], [2 , 6 ], [3 , 5 ]], dims = ["a" , "b" ])},
764
- {"a" : slice (None , None , 2 )},
765
- ]
766
- multiple_indexing (indexers4 )
767
-
768
- # vectorized-integer mixed
769
- indexers5 = [
770
- {"dim3" : 0 },
771
- {"dim1" : DataArray ([[0 , 7 ], [2 , 6 ], [3 , 5 ]], dims = ["a" , "b" ])},
772
- {"a" : 1 , "b" : 0 },
773
- ]
774
- multiple_indexing (indexers5 )
775
-
776
- def test_vectorized_indexing_negative_step (self ) -> None :
777
- # use dask explicitly when present
778
- open_kwargs : dict [str , Any ] | None
779
- if has_dask :
780
- open_kwargs = {"chunks" : {}}
781
- else :
782
- open_kwargs = None
783
- in_memory = create_test_data ()
784
-
785
- def multiple_indexing (indexers ):
786
- # make sure a sequence of lazy indexings certainly works.
787
- with self .roundtrip (in_memory , open_kwargs = open_kwargs ) as on_disk :
788
- actual = on_disk ["var3" ]
789
- expected = in_memory ["var3" ]
790
- for ind in indexers :
791
- actual = actual .isel (ind )
792
- expected = expected .isel (ind )
793
- # make sure the array is not yet loaded into memory
794
- assert not actual .variable ._in_memory
795
- assert_identical (expected , actual .load ())
796
-
797
- # with negative step slice.
798
- indexers = [
799
- {
800
- "dim1" : DataArray ([[0 , 7 ], [2 , 6 ], [3 , 5 ]], dims = ["a" , "b" ]),
801
- "dim3" : slice (- 1 , 1 , - 1 ),
802
- }
803
- ]
804
- multiple_indexing (indexers )
805
-
806
- # with negative step slice.
807
- indexers = [
808
- {
809
- "dim1" : DataArray ([[0 , 7 ], [2 , 6 ], [3 , 5 ]], dims = ["a" , "b" ]),
810
- "dim3" : slice (- 1 , 1 , - 2 ),
811
- }
812
- ]
813
- multiple_indexing (indexers )
814
-
815
- def test_outer_indexing_reversed (self ) -> None :
816
- # regression test for GH6560
817
- ds = xr .Dataset (
818
- {"z" : (("t" , "p" , "y" , "x" ), np .ones ((1 , 1 , 31 , 40 )))},
819
- )
820
-
821
- with self .roundtrip (ds ) as on_disk :
822
- subset = on_disk .isel (t = [0 ], p = 0 ).z [:, ::10 , ::10 ][:, ::- 1 , :]
823
- assert subset .sizes == subset .load ().sizes
824
-
825
- def test_isel_dataarray (self ) -> None :
826
- # Make sure isel works lazily. GH:issue:1688
827
- in_memory = create_test_data ()
828
- with self .roundtrip (in_memory ) as on_disk :
829
- expected = in_memory .isel (dim2 = in_memory ["dim2" ] < 3 )
830
- actual = on_disk .isel (dim2 = on_disk ["dim2" ] < 3 )
831
- assert_identical (expected , actual )
832
-
833
835
def validate_array_type (self , ds ):
834
836
# Make sure that only NumpyIndexingAdapter stores a bare np.ndarray.
835
837
def find_and_validate_array (obj ):
0 commit comments