def __getitem__(self, slices): # It supports the basic indexing (by slices, ints or Ellipsis) only. # TODO(beam2d): Support the advanced indexing of NumPy. if not isinstance(slices, tuple): slices = [slices] else: slices = list(slices) if any(isinstance(s, ndarray) for s in slices): raise ValueError('Advanced indexing is not supported') # Expand ellipsis into empty slices n_newaxes = slices.count(newaxis) n_ellipses = slices.count(Ellipsis) if n_ellipses > 0: if n_ellipses > 1: raise ValueError('Only one Ellipsis is allowed in index') ellipsis = slices.index(Ellipsis) ellipsis_size = self.ndim - (len(slices) - n_newaxes - 1) slices[ellipsis:ellipsis + 1] = [slice(None)] * ellipsis_size slices += [slice(None)] * (self.ndim - len(slices) + n_newaxes) # Create new shape and stride shape = [] strides = [] j = 0 offset = 0 for i, s in enumerate(slices): if s is newaxis: shape.append(1) if j < self.ndim: strides.append(self._strides[j]) elif self.ndim > 0: strides.append(self._strides[-1]) else: strides.append(self.itemsize) elif isinstance(s, slice): s = internal.complete_slice(s, self._shape[j]) if s.step > 0: dim = (s.stop - s.start - 1) // s.step + 1 else: dim = (s.stop - s.start + 1) // s.step + 1 shape.append(dim) strides.append(self._strides[j] * s.step) offset += s.start * self._strides[j] j += 1 elif numpy.isscalar(s): s = int(s) if s >= self._shape[j]: raise IndexError( 'Index %s exceeds the size %s at axis %s' % (s, self._shape[j], j)) offset += s * self._strides[j] j += 1 else: raise TypeError('Invalid index type: %s' % type(slices[i])) v = self.view() v._shape = tuple(shape) v._strides = tuple(strides) v._size = internal.prod(shape) v.data = self.data + offset v._c_contiguous = -1 v._f_contiguous = -1 return v
def __getitem__(self, slices): # It supports the basic indexing (by slices, ints or Ellipsis) only. # TODO(beam2d): Support the advanced indexing of NumPy. if not isinstance(slices, tuple): slices = [slices] else: slices = list(slices) if six.moves.builtins.any(isinstance(s, ndarray) for s in slices): raise ValueError('Advanced indexing is not supported') # Expand ellipsis into empty slices n_newaxes = slices.count(newaxis) n_ellipses = slices.count(Ellipsis) if n_ellipses > 0: if n_ellipses > 1: raise ValueError('Only one Ellipsis is allowed in index') ellipsis = slices.index(Ellipsis) ellipsis_size = self.ndim - (len(slices) - n_newaxes - 1) slices[ellipsis:ellipsis + 1] = [slice(None)] * ellipsis_size slices += [slice(None)] * (self.ndim - len(slices) + n_newaxes) # Create new shape and stride shape = [] strides = [] j = 0 offset = 0 for i, s in enumerate(slices): if s is newaxis: shape.append(1) if j < self.ndim: strides.append(self._strides[j]) elif self.ndim > 0: strides.append(self._strides[-1]) else: strides.append(self.itemsize) elif isinstance(s, slice): s = internal.complete_slice(s, self._shape[j]) if s.step > 0: dim = (s.stop - s.start - 1) // s.step + 1 else: dim = (s.stop - s.start + 1) // s.step + 1 shape.append(dim) strides.append(self._strides[j] * s.step) offset += s.start * self._strides[j] j += 1 elif numpy.isscalar(s): s = int(s) if s >= self._shape[j]: raise IndexError('Index %s exceeds the size %s at axis %s' % (s, self._shape[j], j)) offset += s * self._strides[j] j += 1 else: raise TypeError('Invalid index type: %s' % type(slices[i])) v = self.view() v._shape = tuple(shape) v._strides = tuple(strides) v._size = internal.prod(shape) v.data = self.data + offset v._c_contiguous = -1 v._f_contiguous = -1 return v
def test_invalid_step_value(self): with self.assertRaises(ValueError): internal.complete_slice(slice(1, 1, 0), 1)
def test_invalid_stop_type(self): with self.assertRaises(IndexError): internal.complete_slice(slice((1, 2), 1, 1), 1) with self.assertRaises(IndexError): internal.complete_slice(slice((1, 2), 1, -1), 1)
def test_complete_slice(self): self.assertEqual( internal.complete_slice(slice(*self.slice), 10), slice(*self.expect))