pytabula

pytabula

Discord Static Badge Static Badge PyPI - License PyPI - Version PyPI - Python Version GitHub Workflow Status (with event) CodeQL

pytabula is a Python library for a tabular data based on collections.abc.Sequence.

A table is a sequence of items organized in rows and columns, much like a spreadsheet. Although it is missing from Python standard library, there are numerous alternative solutions.

pytabula.Table is designed to be minimal and intuitive subclass of the Sequence class. Table, as such is a sequence of rows, with each row being a sequence of individual items. Rows are indexed numerically and columns are named, allowing every item to be referenced by (row, column) pair.

Install

pytabula can be easily pip installed.

First create and/or activate virtual environment:

$ python3.11 -m venv venv
$ source venv/bin/activate
(venv) $

pip install pytabula into virtual environment:

(venv) $ python -m pip install pytabula
Collecting pytabula
  Using cached pytabula-0.2.0-py3-none-any.whl (5.9 kB)
Installing collected packages: pytabula
Successfully installed pytabula-0.2.0
(venv) $

Check that pytabula is importable:

(venv) $ python -c "import pytabula as pt; print(pt.__pytabula__)"
p     y     t    a     b    u    l   a
----- ----- ---- ----- ---- ---- --- -----
━━━━  ━━━━  ┏┓━  ━━━━  ┓━━  ━━━  ┓━  ━━━━
━━━━  ━━━━  ┛┗┓  ━━━━  ┃━━  ━━━  ┃━  ━━━━
┏━━┓  ┓━┏┓  ┓┏┛  ━━┓━  ┗━┓  ┓┏┓  ┃━  ━━┓━
┃┏┓┃  ┃━┃┃  ┃┃━  ━┓┃━  ┏┓┃  ┃┃┃  ┃━  ━┓┃━
┃┗┛┃  ┗━┛┃  ┃┗┓  ┗┛┗┓  ┗┛┃  ┗┛┃  ┗┓  ┗┛┗┓
┃┏━┛  ━┓┏┛  ┗━┛  ━━━┛  ━━┛  ━━┛  ━┛  ━━━┛
┃┃━━  ━┛┃━  ━━━  ━━━━  ━━━  ━━━  ━━  ━━━━
┗┛━━  ━━┛━  ━━━  ━━━━  ━━━  ━━━  ━━  ━━━━

(venv) $

Use

pytabula introduces two classes, namely Table and MutableTable, as subclasses of Sequence and MutableSequence. This implies that you can utilize Table and MutableTable in a manner similar to how you would use tuple and list, respectively. In this context, we'll exclusively showcase the enhancements made to this API.

>>> # import
>>> import pytabula as tbl

>>> # initialization
>>> t = tbl.Table([
...     ('ozzy', 'dog', 18),
...     ('marry', 'cat', 10),
... ], columns=('name', 'animal', 'age'))

>>> print(t)
name   animal  age
------ ------- ----
ozzy   dog       18
marry  cat       10

Table operations

Common Table Operations

Check common sequence operations for full overview.

Contains

show/hide sequence api
Sequence
>>> # row in table
>>> ('marry', 'cat', 10) in t
True

>>> # item in table
>>> any('dog' in row for row in t)
True

>>> # row not in table
>>> ('ozzy', 'cat', 18) not in t
True

>>> # item not in table
>>> any('bird' not in row for row in t)
True

Table
>>> # row in table
>>> ('marry', 'cat', 10) in t
True

>>> # item in table
>>> 'dog' in t
True

>>> # row not in table
>>> ('ozzy', 'cat', 18) not in t
True

>>> # item not in table
>>> 'bird' not in t
True

Get item

show/hide sequence api
Sequence
>>> import enum
>>> class Col(enum.IntEnum):
...     NAME = 0
...     ANIMAL = 1
...     AGE = 2

>>> # row indexing
>>> t[0]
('ozzy', 'dog', 18)

>>> # item indexing
>>> t[1][Col.ANIMAL]
'cat'

>>> # row slicing
>>> t[:1]
Table([('ozzy', 'dog', 18)], columns=('name', 'animal', 'age'))

>>> # column slicing
>>> t[0][:Col.AGE]
('ozzy', 'dog')

>>> # rectangle
>>> tbl.Table([r[:Col.AGE] for r in t[:1]], columns=t.columns[:Col.AGE])
Table([('ozzy', 'dog')], columns=('name', 'animal'))

Table
>>> # import enum
>>> # class Col(enum.IntEnum):
>>> #     NAME = 0
>>> #     ANIMAL = 1
>>> #     AGE = 2

>>> # row indexing
>>> t[0]
('ozzy', 'dog', 18)

>>> # item indexing
>>> t[1, 'animal']
'cat'

>>> # row slicing
>>> t[:1]
Table([('ozzy', 'dog', 18)], columns=('name', 'animal', 'age'))

>>> # column slicing
>>> t[0, :'age']
('ozzy', 'dog')

>>> # rectangle
>>> t[:1, :'age']
Table([('ozzy', 'dog')], columns=('name', 'animal'))

Index and count

show/hide sequence api
Sequence
>>> # row index
>>> t.index(('marry', 'cat', 10))
1

>>> # item index
>>> row, col = next((i, Col(r.index(18))) for i, r in enumerate(t) if 18 in r)
>>> row, col
(0, <Col.AGE: 2>)

>>> t[row][col]
18

>>> # row count
>>> t.count(('ozzy', 'dog', 18))
1

>>> # item count
>>> sum(r.count('cat') for r in t)
1

Table
>>> # row index
>>> t.index(('marry', 'cat', 10))
1

>>> # item index
>>> row, col = t.index(18)
>>> row, col
(0, 'age')

>>> t[row, col]
18

>>> # row count
>>> t.count(('ozzy', 'dog', 18))
1

>>> # item count
>>> t.count('cat')
1

Immutable Table types

Check immutable sequence types for full overview.

Mutable Table operations

Check mutable sequence types for full overview.

Set item

show/hide sequence api
Sequence
>>> mt = tbl.MutableTable(list(t), columns=t.columns)

>>> # row update
>>> mt[0] = ('harry', 'mouse', 2)
>>> print(mt)
name   animal  age
------ ------- ----
harry  mouse      2
marry  cat       10

>>> # item update
>>> mt[0][Col.ANIMAL] = 'python'
>>> print(mt)
name   animal  age
------ ------- ----
harry  python     2
marry  cat       10

>>> # slice update
>>> for row, value in zip(mt, [('rabbit', 3), ('spider', 1)]):
...     row[Col.ANIMAL:] = value
>>> print(mt)
name   animal  age
------ ------- ----
harry  rabbit     3
marry  spider     1

Table
>>> mt = tbl.MutableTable(list(t), columns=t.columns)

>>> # row update
>>> mt[0] = ('harry', 'mouse', 2)
>>> print(mt)
name   animal  age
------ ------- ----
harry  mouse      2
marry  cat       10

>>> # item update
>>> mt[0, 'animal'] = 'python'
>>> print(mt)
name   animal  age
------ ------- ----
harry  python     2
marry  cat       10

>>> # slice update

>>> mt[:, 'animal':] = tbl.Table([('rabbit', 3), ('spider', 1)])
>>> print(mt)
name   animal  age
------ ------- ----
harry  rabbit     3
marry  spider     1

Append column
show/hide sequence api
Sequence
>>> mt = tbl.MutableTable(list(t), columns=t.columns)

>>> for row, value in zip(mt, ('chicken', 'fish')):
...     row.append(value)
>>> mt.columns.append('food')
>>> print(mt)
name   animal  age  food
------ ------- ---- --------
ozzy   dog       18 chicken
marry  cat       10 fish

Table
>>> mt = tbl.MutableTable(list(t), columns=t.columns)



>>> mt[:, 'food'] = ('chicken', 'fish')
>>> print(mt)
name   animal  age  food
------ ------- ---- --------
ozzy   dog       18 chicken
marry  cat       10 fish

Insert column(s)
show/hide sequence api
Sequence
>>> mt = tbl.MutableTable(list(t), columns=t.columns)

>>> for row, value in zip(mt, ('big', 'small')):
...     row[Col.AGE: Col.AGE] = (value,)
>>> mt.columns[Col.AGE: Col.AGE] = ('size',)
>>> print(mt)
name   animal  size   age
------ ------- ------ ----
ozzy   dog     big      18
marry  cat     small    10

Table
>>> mt = tbl.MutableTable(list(t), columns=t.columns)



>>> mt[:, 'age':'age'] = tbl.Table([('big',), ('small',)], columns=('size',))
>>> print(mt)
name   animal  size   age
------ ------- ------ ----
ozzy   dog     big      18
marry  cat     small    10

Delete item

show/hide sequence api
Sequence
>>> mt = tbl.MutableTable(list(t), columns=t.columns)

>>> # row deleting
>>> del mt[1]
>>> print(mt)
name  animal  age
----- ------- ----
ozzy  dog       18

>>> # column deleting
>>> for row in mt:
...     del row[Col.AGE]
>>> del mt.columns[Col.AGE]
>>> print(mt)
name  animal
----- -------
ozzy  dog

Table
>>> mt = tbl.MutableTable(list(t), columns=t.columns)

>>> # row deleting
>>> del mt[1]
>>> print(mt)
name  animal  age
----- ------- ----
ozzy  dog       18

>>> # column deleting


>>> del mt[:, 'age']
>>> print(mt)
name  animal
----- -------
ozzy  dog