def __setitem__(self, key, value): """Set a row, a range of rows or a slice in the array. It takes different actions depending on the type of the key parameter: if it is an integer, the corresponding array row is set to value (the value is broadcast when needed). If key is a slice, the row slice determined by it is set to value (as usual, if the slice to be updated exceeds the actual shape of the array, only the values in the existing range are updated). If value is a multidimensional object, then its shape must be compatible with the shape determined by key, otherwise, a ValueError will be raised. Furthermore, NumPy-style fancy indexing, where a list of indices in a certain axis is specified, is also supported. Note that only one list per selection is supported right now. Finally, NumPy-style point and boolean selections are supported as well. Examples -------- :: a1[0] = 333 # assign an integer to a Integer Array row a2[0] = 'b' # assign a string to a string Array row a3[1:4] = 5 # broadcast 5 to slice 1:4 a4[1:4:2] = 'xXx' # broadcast 'xXx' to slice 1:4:2 # General slice update (a5.shape = (4,3,2,8,5,10). a5[1, ..., ::2, 1:4, 4:] = numpy.arange(1728, shape=(4,3,2,4,3,6)) a6[1, [1,5,10], ..., -1] = arr # fancy selection a7[np.where(a6[:] > 4)] = 4 # point selection + broadcast a8[arr > 4] = arr2 # boolean selection """ self._g_check_open() # Create an array compliant with the specified slice nparr = convert_to_np_atom2(value, self.atom) if nparr.size == 0: return # truncate data if least_significant_digit filter is set # TODO: add the least_significant_digit attribute to the array on disk if self.filters.least_significant_digit is not None and not numpy.issubdtype(nparr.dtype, int): nparr = quantize(nparr, self.filters.least_significant_digit) try: startl, stopl, stepl, shape = self._interpret_indexing(key) self._write_slice(startl, stopl, stepl, shape, nparr) except TypeError: # Then, try with a point-wise selection try: coords = self._point_selection(key) self._write_coords(coords, nparr) except TypeError: selection, reorder, shape = self._fancy_selection(key) self._write_selection(selection, reorder, shape, nparr)
def __setitem__(self, key, value): """Set a row, a range of rows or a slice in the array. It takes different actions depending on the type of the key parameter: if it is an integer, the corresponding array row is set to value (the value is broadcast when needed). If key is a slice, the row slice determined by it is set to value (as usual, if the slice to be updated exceeds the actual shape of the array, only the values in the existing range are updated). If value is a multidimensional object, then its shape must be compatible with the shape determined by key, otherwise, a ValueError will be raised. Furthermore, NumPy-style fancy indexing, where a list of indices in a certain axis is specified, is also supported. Note that only one list per selection is supported right now. Finally, NumPy-style point and boolean selections are supported as well. Examples -------- :: a1[0] = 333 # assign an integer to a Integer Array row a2[0] = 'b' # assign a string to a string Array row a3[1:4] = 5 # broadcast 5 to slice 1:4 a4[1:4:2] = 'xXx' # broadcast 'xXx' to slice 1:4:2 # General slice update (a5.shape = (4,3,2,8,5,10). a5[1, ..., ::2, 1:4, 4:] = numpy.arange(1728, shape=(4,3,2,4,3,6)) a6[1, [1,5,10], ..., -1] = arr # fancy selection a7[np.where(a6[:] > 4)] = 4 # point selection + broadcast a8[arr > 4] = arr2 # boolean selection """ self._g_check_open() # Create an array compliant with the specified slice nparr = convert_to_np_atom2(value, self.atom) if nparr.size == 0: return try: startl, stopl, stepl, shape = self._interpret_indexing(key) self._write_slice(startl, stopl, stepl, shape, nparr) except TypeError: # Then, try with a point-wise selection try: coords = self._point_selection(key) self._write_coords(coords, nparr) except TypeError: selection, reorder, shape = self._fancy_selection(key) self._write_selection(selection, reorder, shape, nparr)
def append(self, sequence): """Add a sequence of data to the end of the dataset. The sequence must have the same type as the array; otherwise a TypeError is raised. In the same way, the dimensions of the sequence must conform to the shape of the array, that is, all dimensions must match, with the exception of the enlargeable dimension, which can be of any length (even 0!). If the shape of the sequence is invalid, a ValueError is raised. """ self._g_check_open() self._v_file._check_writable() # Convert the sequence into a NumPy object nparr = convert_to_np_atom2(sequence, self.atom) # Check if it has a consistent shape with underlying EArray self._check_shape_append(nparr) # If the size of the nparr is zero, don't do anything else if nparr.size > 0: self._append(nparr)
def append(self, sequence): """Add a sequence of data to the end of the dataset. This method appends the objects in the sequence to a *single row* in this array. The type and shape of individual objects must be compliant with the atoms in the array. In the case of serialized objects and variable length strings, the object or string to append is itself the sequence. """ self._g_check_open() self._v_file._check_writable() # Prepare the sequence to convert it into a NumPy object atom = self.atom if not hasattr(atom, 'size'): # it is a pseudo-atom sequence = atom.toarray(sequence) statom = atom.base else: try: # fastest check in most cases len(sequence) except TypeError: raise TypeError("argument is not a sequence") statom = atom if len(sequence) > 0: # The sequence needs to be copied to make the operation safe # to in-place conversion. nparr = convert_to_np_atom2(sequence, statom) nobjects = self._getnobjects(nparr) else: nobjects = 0 nparr = None self._append(nparr, nobjects) self.nrows += 1