Exemplo n.º 1
0
    def _assign_values(self, coords, values):
        """Assign the `values` to the positions stated in `coords`."""

        for nrow, value in zip(coords, values):
            if nrow >= self.nrows:
                raise IndexError("First index out of range")
            if nrow < 0:
                # To support negative values
                nrow += self.nrows
            object_ = value
            # Prepare the object to convert it into a NumPy object
            atom = self.atom
            if not hasattr(atom, 'size'):  # it is a pseudo-atom
                object_ = atom.toarray(object_)
                statom = atom.base
            else:
                statom = atom
            value = convertToNPAtom(object_, statom)
            nobjects = self._getnobjects(value)

            # Get the previous value
            nrow = idx2long(nrow)  # To convert any possible numpy scalar value
            nparr = self._readArray(nrow, nrow + 1, 1)[0]
            nobjects = len(nparr)
            if len(value) > nobjects:
                raise ValueError("Length of value (%s) is larger than number "
                                 "of elements in row (%s)" %
                                 (len(value), nobjects))
            try:
                nparr[:] = value
            except Exception, exc:  #XXX
                raise ValueError(
                    "Value parameter:\n'%r'\n"
                    "cannot be converted into an array object compliant "
                    "vlarray[%s] row: \n'%r'\nThe error was: <%s>" %
                    (value, nrow, nparr[:], exc))

            if nparr.size > 0:
                self._modify(nrow, nparr, nobjects)
Exemplo n.º 2
0
    def _assign_values(self, coords, values):
        """Assign the `values` to the positions stated in `coords`."""

        for nrow, value in zip(coords, values):
            if nrow >= self.nrows:
                raise IndexError("First index out of range")
            if nrow < 0:
                # To support negative values
                nrow += self.nrows
            object_ = value
            # Prepare the object to convert it into a NumPy object
            atom = self.atom
            if not hasattr(atom, 'size'):  # it is a pseudo-atom
                object_ = atom.toarray(object_)
                statom = atom.base
            else:
                statom = atom
            value = convertToNPAtom(object_, statom)
            nobjects = self._getnobjects(value)

            # Get the previous value
            nrow = idx2long(nrow)   # To convert any possible numpy scalar value
            nparr = self._readArray(nrow, nrow+1, 1)[0]
            nobjects = len(nparr)
            if len(value) > nobjects:
                raise ValueError("Length of value (%s) is larger than number "
                                 "of elements in row (%s)" % (len(value),
                                                              nobjects))
            try:
                nparr[:] = value
            except Exception, exc:  #XXX
                raise ValueError("Value parameter:\n'%r'\n"
                        "cannot be converted into an array object compliant "
                        "vlarray[%s] row: \n'%r'\nThe error was: <%s>" %
                                                (value, nrow, nparr[:], exc))

            if nparr.size > 0:
                self._modify(nrow, nparr, nobjects)
    def __setitem__(self, keys, value):
        """
        Set a row 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`.  If `key` is a tuple, the first element refers
        to the row to be modified, and the second element to the range
        within the row to be updated with the `value` (so it can be an
        integer or a slice).

        The type and shape of the `value` must be compatible with the
        type and shape determined by the `key`, otherwise, a
        ``TypeError`` or a ``ValueError`` will be raised.

        .. Note:: When updating the rows of a `VLArray` object which
           uses a pseudo-atom, there is a problem: you can only update
           values with *exactly* the same size in bytes than the
           original row.  This is very difficult to meet with
           ``object`` pseudo-atoms, because ``cPickle`` applied on a
           Python object does not guarantee to return the same number
           of bytes than over another object, even if they are of the
           same class.  This effectively limits the kinds of objects
           than can be updated in variable-length arrays.

        Example of use::

            vlarray[0] = vlarray[0] * 2 + 3
            vlarray[99, 3:] = arange(96) * 2 + 3
            # Negative values for start and stop (but not step) are supported.
            vlarray[99, -99:-89:2] = vlarray[5] * 2 + 3
        """

        self._v_file._checkWritable()

        if not isinstance(keys, tuple):
            keys = (keys, None)
        if len(keys) > 2:
            raise IndexError, "You cannot specify more than two dimensions"
        nrow, rng = keys
        # Process the first index
        if not (type(nrow) in (int,long) or isinstance(nrow, numpy.integer)):
            raise IndexError, "The first dimension only can be an integer"
        if nrow >= self.nrows:
            raise IndexError, "First index out of range"
        if nrow < 0:
            # To support negative values
            nrow += self.nrows
        # Process the second index
        if type(rng) in (int,long) or isinstance(rng, numpy.integer):
            start = rng; stop = start+1; step = 1
        elif isinstance(rng, slice):
            start, stop, step = rng.start, rng.stop, rng.step
        elif rng is None:
            start, stop, step = None, None, None
        else:
            raise IndexError, "Non-valid second index or slice: %s" % rng

        object = value
        # Prepare the object to convert it into a NumPy object
        atom = self.atom
        if not hasattr(atom, 'size'):  # it is a pseudo-atom
            object = atom.toarray(object)
            statom = atom.base
        else:
            statom = atom
        value = convertToNPAtom(object, statom)
        nobjects = self._getnobjects(value)

        # Get the previous value
        nrow = idx2long(nrow)   # To convert any possible numpy scalar value
        nparr = self._readArray(nrow, nrow+1, 1)[0]
        nobjects = len(nparr)
        if len(value) > nobjects:
            raise ValueError, \
"Length of value (%s) is larger than number of elements in row (%s)" % \
(len(value), nobjects)
        # Assign the value to it
        # The values can be numpy scalars. Convert them before building the slice.
        if start is not None: start = idx2long(start)
        if stop is not None: stop = idx2long(stop)
        if step is not None: step = idx2long(step)
        try:
            nparr[slice(start, stop, step)] = value
        except Exception, exc:  #XXX
            raise ValueError, \
"Value parameter:\n'%r'\ncannot be converted into an array object compliant vlarray[%s] row: \n'%r'\nThe error was: <%s>" % \
        (value, keys, nparr[slice(start, stop, step)], exc)