def removeDataFrameRows(self, rows): """ Removes rows from the dataframe. :param rows: (list) of row indexes to removes. :return: (bool) True on success, False on failure. """ if not self.editable: return False if rows: position = min(rows) count = len(rows) self.beginRemoveRows(QtCore.QModelIndex(), position, position + count - 1) removedAny = False for idx, line in self._dataFrame.iterrows(): if idx in rows: removedAny = True self._dataFrame.drop(idx, inplace=True) if not removedAny: return False self._dataFrame.reset_index(inplace=True, drop=True) self.endRemoveRows() return True return False
def removeDataFrameColumns(self, columns): """ Removes columns from the dataframe. :param columns: [(int, str)] :return: (bool) True on success, False on failure. """ if not self.editable: return False if columns: deleted = 0 errored = False for (position, name) in columns: position = position - deleted if position < 0: position = 0 self.beginRemoveColumns(QtCore.QModelIndex(), position, position) try: self._dataFrame.drop(name, axis=1, inplace=True) except ValueError as e: errored = True continue self.endRemoveColumns() deleted += 1 self.dataChanged.emit() if errored: return False else: return True return False
def columnCount(self, index=QtCore.QModelIndex()): """returns number of columns Args: index (QtCore.QModelIndex, optional): Index to define column and row. defaults to empty QModelIndex Returns: number of columns """ return len(self.headers)
def rowCount(self, index=QtCore.QModelIndex()): """returns number of rows Args: index (QtCore.QModelIndex, optional): Index to define column and row. defaults to empty QModelIndex Returns: number of rows """ return len(self._dataFrame.columns)
def columnCount(self, index=QtCore.QModelIndex()): """returns number of columns Args: index (QtCore.QModelIndex, optional): Index to define column and row. defaults to empty QModelIndex Returns: number of columns """ # speed comparison: # In [23]: %timeit len(df.columns) # 10000000 loops, best of 3: 108 ns per loop # In [24]: %timeit df.shape[1] # 1000000 loops, best of 3: 440 ns per loop return len(self._dataFrame.columns)
def addDataFrameRows(self, count=1): """ Adds rows to the dataframe. :param count: (int) The number of rows to add to the dataframe. :return: (bool) True on success, False on failure. """ # don't allow any gaps in the data rows. # and always append at the end if not self.editable: return False position = self.rowCount() if count < 1: return False if len(self.dataFrame().columns) == 0: # log an error message or warning return False # Note: This function emits the rowsAboutToBeInserted() signal which # connected views (or proxies) must handle before the data is # inserted. Otherwise, the views may end up in an invalid state. self.beginInsertRows(QtCore.QModelIndex(), position, position + count - 1) defaultValues = [] for dtype in self._dataFrame.dtypes: if dtype.type == numpy.dtype('<M8[ns]'): val = pandas.Timestamp('') elif dtype.type == numpy.dtype(object): val = '' else: val = dtype.type() defaultValues.append(val) for i in range(count): self._dataFrame.loc[position + i] = defaultValues self._dataFrame.reset_index() self.endInsertRows() return True
def rowCount(self, index=QtCore.QModelIndex()): """returns number of rows Args: index (QtCore.QModelIndex, optional): Index to define column and row. defaults to empty QModelIndex Returns: number of rows """ # len(df.index) is faster, so use it: # In [12]: %timeit df.shape[0] # 1000000 loops, best of 3: 437 ns per loop # In [13]: %timeit len(df.index) # 10000000 loops, best of 3: 110 ns per loop # %timeit df.__len__() # 1000000 loops, best of 3: 215 ns per loop return len(self._dataFrame.index)
def addDataFrameColumn(self, columnName, dtype=str, defaultValue=None): """ Adds a column to the dataframe as long as the model's editable property is set to True and the dtype is supported. :param columnName: str name of the column. :param dtype: qtpandas.models.SupportedDtypes option :param defaultValue: (object) to default the column's value to, should be the same as the dtype or None :return: (bool) True on success, False otherwise. """ if not self.editable or dtype not in SupportedDtypes.allTypes(): return False elements = self.rowCount() columnPosition = self.columnCount() newColumn = pandas.Series([defaultValue] * elements, index=self._dataFrame.index, dtype=dtype) self.beginInsertColumns(QtCore.QModelIndex(), columnPosition - 1, columnPosition - 1) try: self._dataFrame.insert(columnPosition, columnName, newColumn, allow_duplicates=False) except ValueError as e: # columnName does already exist return False self.endInsertColumns() self.propagateDtypeChanges(columnPosition, newColumn.dtype) return True
def test_data(self, dataframe): model = ColumnDtypeModel(dataFrame=dataframe) index = model.index(0, 0) # get data for display role ret = index.data() assert ret == 'Foo' # edit role does the same as display role ret = index.data(Qt.EditRole) assert ret == 'Foo' # datatype only defined for column 1 ret = index.data(DTYPE_ROLE) assert ret == None # datatype column index = index.sibling(0, 1) ret = index.data(DTYPE_ROLE) assert ret == numpy.dtype(numpy.int64) # check translation / display text assert index.data( ) == 'integer (64 bit)' == SupportedDtypes.description(ret) # column not defined index = index.sibling(0, 2) assert index.data(DTYPE_ROLE) == None # invalid index index = QtCore.QModelIndex() assert model.data(index) == None index = model.index(2, 0) # get data for display role ret = index.data() assert ret == 'Spam'
def test_invalidIndex(self, model): assert model.setData(QtCore.QModelIndex(), None) == False
def test_invalidIndex(self, model): assert model.data(QtCore.QModelIndex()) is None