> built 2026-09-15 13:07 UTC from 2929fed (master) · tabled 0.1.29. Details: build_info.json

# index.html.md

<!-- generated by epythet -->

# tabled

A (key-value) data-object-layer to get (pandas) tables from a variety of sources with ease

To install:	`pip install tabled`

<!-- epythet:agentic-readme:start -->

## For AI agents

`tabled` publishes its documentation in forms made for coding agents. If you are one, start here.

**The documentation, machine-readable**: [`llms.txt`](https://i2mint.github.io/tabled/llms.txt) indexes every page; [`tabled.md`](https://i2mint.github.io/tabled/tabled.md) is the whole documentation in one file; every page has a `.md` twin; [`objects.inv`](https://i2mint.github.io/tabled/objects.inv) maps symbols to URLs.

If you still read documentation with your own eyes, the rest of this README is written for you, starting at [SQLite Database Support]().

<!-- epythet:agentic-readme:end -->

## SQLite Database Support

Tabled provides seamless integration with SQLite databases through `DfFiles`:

```python
from tabled import DfFiles

# Automatic SQLite detection - just pass the database file path
df_files = DfFiles('my_database.db')

# Access tables as DataFrames
customers = df_files['customers.parquet']  # Full filename
orders = df_files['orders']                # Clean table name (both work)

# List available tables
print(list(df_files.keys()))  # ['customers.parquet', 'orders.parquet', ...]

# Or use the explicit method
df_files = DfFiles.from_sqlite_file('my_database.db')
```

Under the hood, SQLite tables are exported to temporary Parquet files for efficient access, with automatic cleanup when the program exits.

### SQLite Export Tools

For more control over SQLite data extraction, use the `sqlite_tools` module:

```python
from tabled.sqlite_tools import export_sqlite_to_dataframes, export_sqlite_to_parquet

# Export to DataFrames
tables = export_sqlite_to_dataframes('database.db')
customers_df = tables['customers']

# Export to Parquet files
export_sqlite_to_parquet('database.db', 'output_directory/')
```

## Table Analysis and Diagnosis

The `dataframe_info` function provides flexible analysis of pandas DataFrames:

```python
from tabled.diagnose import dataframe_info, register_info_func
import pandas as pd

# Analyze a DataFrame
df = pd.DataFrame({'a': [1, 2, 3], 'b': ['x', 'y', 'z']})
info = dataframe_info(df)
print(info['shape'])  # (3, 2)
print(info['columns'])  # ['a', 'b']

# Extend with custom analysis functions
def memory_usage(df):
    return df.memory_usage(deep=True).sum()

register_info_func('memory', memory_usage)
info = dataframe_info(df)
print(info['memory'])  # Memory usage in bytes
```

The analysis is completely customizable - you can register new analysis functions or provide custom info function dictionaries to focus on specific aspects of your data.

# DfFiles

This section demonstrates how to use `DfFiles` to store and retrieve pandas DataFrames using various file formats.

## Setup

First, let’s import required packages and define our test data:

```python
import os
import shutil
import tempfile

import pandas as pd
from tabled import DfFiles

# Test data dictionary
misc_small_dicts = {
    "fantasy_tavern_menu": {
        "item": ["Dragon Ale", "Elf Bread", "Goblin Stew"],
        "price": [7.5, 3.0, 5.5],
        "is_alcoholic": [True, False, False],
        "servings_left": [12, 25, 8],
    },
    "alien_abduction_log": {
        "abductee_name": ["Bob", "Alice", "Zork"],
        "location": ["Kansas City", "Roswell", "Jupiter"],
        "duration_minutes": [15, 120, 30],
        "was_returned": [True, False, True],
    }
}
```

## Creating Test Directory

We’ll create a temporary directory for our files:

```python
def create_test_directory():
    # Create a directory for the test files
    rootdir = os.path.join(tempfile.gettempdir(), 'tabled_df_files_test')
    if os.path.exists(rootdir):
        shutil.rmtree(rootdir)
    os.makedirs(rootdir)
    print(f"Created directory at: {rootdir}")
    return rootdir

rootdir = create_test_directory()
print(f"Created directory at: {rootdir}")
```

```none
Created directory at: /var/folders/mc/c070wfh51kxd9lft8dl74q1r0000gn/T/tabled_df_files_test
Created directory at: /var/folders/mc/c070wfh51kxd9lft8dl74q1r0000gn/T/tabled_df_files_test
```

## Initialize DfFiles

Create a new DfFiles instance pointing to our directory:

```python
df_files = DfFiles(rootdir)
```

Let’s verify it starts empty:

```python
list(df_files)
```

```none
[]
```

## Creating and Saving DataFrames

Let’s create DataFrames from our test data:

```python
fantasy_tavern_menu_df = pd.DataFrame(misc_small_dicts['fantasy_tavern_menu'])
alien_abduction_log_df = pd.DataFrame(misc_small_dicts['alien_abduction_log'])

print("Fantasy Tavern Menu:")
display(fantasy_tavern_menu_df)
print("\nAlien Abduction Log:")
display(alien_abduction_log_df)
```

```none
Fantasy Tavern Menu:
```

<div>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>item</th>
      <th>price</th>
      <th>is_alcoholic</th>
      <th>servings_left</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>Dragon Ale</td>
      <td>7.5</td>
      <td>True</td>
      <td>12</td>
    </tr>
    <tr>
      <th>1</th>
      <td>Elf Bread</td>
      <td>3.0</td>
      <td>False</td>
      <td>25</td>
    </tr>
    <tr>
      <th>2</th>
      <td>Goblin Stew</td>
      <td>5.5</td>
      <td>False</td>
      <td>8</td>
    </tr>
  </tbody>
</table>
</div>
```none
Alien Abduction Log:
```

<div>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>abductee_name</th>
      <th>location</th>
      <th>duration_minutes</th>
      <th>was_returned</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>Bob</td>
      <td>Kansas City</td>
      <td>15</td>
      <td>True</td>
    </tr>
    <tr>
      <th>1</th>
      <td>Alice</td>
      <td>Roswell</td>
      <td>120</td>
      <td>False</td>
    </tr>
    <tr>
      <th>2</th>
      <td>Zork</td>
      <td>Jupiter</td>
      <td>30</td>
      <td>True</td>
    </tr>
  </tbody>
</table>
</div>

Now let’s save these DataFrames using different formats:

```python
df_files['fantasy_tavern_menu.csv'] = fantasy_tavern_menu_df
df_files['alien_abduction_log.json'] = alien_abduction_log_df
```

## Reading Data Back

Let’s verify we can read the data back correctly:

```python
saved_df = df_files['fantasy_tavern_menu.csv']
saved_df
```

<div>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>item</th>
      <th>price</th>
      <th>is_alcoholic</th>
      <th>servings_left</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>Dragon Ale</td>
      <td>7.5</td>
      <td>True</td>
      <td>12</td>
    </tr>
    <tr>
      <th>1</th>
      <td>Elf Bread</td>
      <td>3.0</td>
      <td>False</td>
      <td>25</td>
    </tr>
    <tr>
      <th>2</th>
      <td>Goblin Stew</td>
      <td>5.5</td>
      <td>False</td>
      <td>8</td>
    </tr>
  </tbody>
</table>
</div>

## MutableMapping Interface

DfFiles implements the MutableMapping interface, making it behave like a dictionary.

Let’s see how many files we have:

```python
len(df_files)
```

```none
2
```

List all available files:

```python
list(df_files)
```

```none
['fantasy_tavern_menu.csv', 'alien_abduction_log.json']
```

Check if a file exists:

```python
'fantasy_tavern_menu.csv' in df_files
```

```none
True
```

## Supported File Extensions

Let’s see what file formats DfFiles supports out of the box.

(**Note that some of these will require installing extra packages, which you’ll realize if you get an ImportError**)

```python
print("Encoder supported extensions:")
list_of_encoder_supported_extensions = list(df_files.extension_encoder_mapping)
print(*list_of_encoder_supported_extensions, sep=', ')
```

```none
Encoder supported extensions:
csv, txt, tsv, json, html, p, pickle, pkl, npy, parquet, zip, feather, h5, hdf5, stata, dta, sql, sqlite, gbq, xls, xlsx, xml, orc
```

```python
print("Decoder supported extensions:")
list_of_decoder_supported_extensions = list(df_files.extension_decoder_mapping)
print(*list_of_decoder_supported_extensions, sep=', ')
```

```none
Decoder supported extensions:
csv, txt, tsv, parquet, json, html, p, pickle, pkl, xml, sql, sqlite, feather, stata, dta, sas, h5, hdf5, xls, xlsx, orc, sav
```

## Testing Different Extensions

Let’s try saving and loading our test DataFrame in different formats:

```python
extensions_supported_by_encoder_and_decoder = (
    set(list_of_encoder_supported_extensions) & set(list_of_decoder_supported_extensions)
)
sorted(extensions_supported_by_encoder_and_decoder)
```

```none
['csv',
 'dta',
 'feather',
 'h5',
 'hdf5',
 'html',
 'json',
 'orc',
 'p',
 'parquet',
 'pickle',
 'pkl',
 'sql',
 'sqlite',
 'stata',
 'tsv',
 'txt',
 'xls',
 'xlsx',
 'xml']
```

```python

```

```python
def test_extension(ext):
    filename = f'test_file.{ext}'
    try:
        df_files[filename] = fantasy_tavern_menu_df
        df_loaded = df_files[filename]
        # test the decoded df is the same as the one that was saved (round-trip test)
        # Note that we drop the index, since the index is not saved in the file by default for all codecs
        pd.testing.assert_frame_equal(
            fantasy_tavern_menu_df.reset_index(drop=True),
            df_loaded.reset_index(drop=True),
        )
        return True
    except Exception as e:
        return False


test_extensions = [
    'csv',
    'feather',
    'json',
    'orc',
    'parquet',
    'pkl',
    'tsv',  
    # 'dta',  # TODO: fix
    # 'h5',  # TODO: fix
    # 'html',  # TODO: fix
    # 'sql',  # TODO: fix
    # 'xml',  # TODO: fix
]

for ext in test_extensions:
    print("Testing extension:", ext)
    success = test_extension(ext)
    if success:
        print(f"\tExtension {ext}: ✓")
    else:
        print('\033[91m' + f"\tFix extension {ext}: ✗" + '\033[0m')
        
    # marker = '✓' if success else '\033[91m✗\033[0m'
    # print(f"\tExtension {ext}: {marker}")
```

```none
Testing extension: csv
	Extension csv: ✓
Testing extension: feather
	Extension feather: ✓
Testing extension: json
	Extension json: ✓
Testing extension: orc
	Extension orc: ✓
Testing extension: parquet
	Extension parquet: ✓
Testing extension: pkl
	Extension pkl: ✓
Testing extension: tsv
	Extension tsv: ✓
Testing extension: dta
[91m	Fix extension dta: ✗[0m
Testing extension: h5
[91m	Fix extension h5: ✗[0m
Testing extension: html
[91m	Fix extension html: ✗[0m
Testing extension: sql
[91m	Fix extension sql: ✗[0m
Testing extension: xml
[91m	Fix extension xml: ✗[0m
```

<p class="epythet-aggregates">This documentation as a single file: <a href="tabled.md">tabled.md</a> (Markdown, for agents).</p>


# _autosummary/tabled.base.html.md

# tabled.base

Based functionality for tabled

### Functions

| [`convert_collection_to_dataframe_if_possible`](_autosummary/tabled.base.html.md#tabled.base.convert_collection_to_dataframe_if_possible)(x)   | Return `x` as a DataFrame if it is a dict, list, tuple, Series or Index; else `x` unchanged.   |
|---------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
| [`get_table`](_autosummary/tabled.base.html.md#tabled.base.get_table)([table_src, ext, ext_mapping, ...])    | Get a table from a variety of sources.                                                         |
| [`validate_fields`](_autosummary/tabled.base.html.md#tabled.base.validate_fields)(df, key_fields, value_columns)   | Raise `ValueError` if any `key_fields` or `value_columns` are missing from `df`.               |

### Classes

| [`DataframeKvReader`](_autosummary/tabled.base.html.md#tabled.base.DataframeKvReader)(df, key_fields[, ...])   | A Mapping view of a DataFrame, keyed by combinations of columns or index levels.   |
|---------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------|
| [`DfFiles`](_autosummary/tabled.base.html.md#tabled.base.DfFiles)(rootdir, \*[, ...])                | A key-value store providing values as pandas.DataFrames.                           |
| [`DfLocalFileReader`](_autosummary/tabled.base.html.md#tabled.base.DfLocalFileReader)                          |                                                                                    |
| [`DfReader`](_autosummary/tabled.base.html.md#tabled.base.DfReader)(rootdir, \*[, ...])               | A read-only `DfFiles`: writes and deletes raise `NotImplementedError`.             |
| [`KeyFuncReader`](_autosummary/tabled.base.html.md#tabled.base.KeyFuncReader)(mapping[, key])              | A read-only mapping view that transforms keys before lookup in `mapping`.          |

### *class* tabled.base.DataframeKvReader(df, key_fields, value_columns=None)

Bases: [`Mapping`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping)

A Mapping view of a DataFrame, keyed by combinations of columns or index levels.

* **Parameters:**
  * **df** – The DataFrame to wrap.
  * **key_fields** – Field(s) (columns or index levels) to use as keys.
  * **value_columns** – Column(s) to use as values. Defaults to all columns.

Example usage:

```pycon
>>> df = pd.DataFrame({
...     'A': [1, 2, 1],
...     'B': [4, 5, 4],
...     'C': [7, 8, 9],
...     'D': [10, 11, 12]
... })
>>> df
   A  B  C   D
0  1  4  7  10
1  2  5  8  11
2  1  4  9  12
>>> kv_reader = DataframeKvReader(df, ['A', 'B'], ['C', 'D'])
>>> key = (1, 4)
>>> kv_reader[key].reset_index(drop=True)
   C   D
0  7  10
1  9  12
>>> list(kv_reader) == [(1, 4), (2, 5)]
True
```

But what if one (or more) of the key fields is an index level?
The DataframeKvReader can handle that too:

```pycon
>>> df = df.set_index(['A'])
>>> df
   B  C   D
A
1  4  7  10
2  5  8  11
1  4  9  12
>>> kv_reader = DataframeKvReader(df, ['A', 'B'], ['C', 'D'])
>>> key = (1, 4)
>>> kv_reader[key].reset_index(drop=True)
   C   D
0  7  10
1  9  12
>>> list(kv_reader) == [(1, 4), (2, 5)]
True
```

### *class* tabled.base.DfFiles(rootdir, \*, extension_encoder_mapping={'arrow': functools.partial(<function written_bytes>, <function dataframe_to_arrow_bytes>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'csv': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_csv>, index=False), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'dta': functools.partial(<function written_bytes>, functools.partial(<function DataFrame.to_stata>, write_index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'feather': functools.partial(<function written_bytes>, <function DataFrame.to_feather>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'gbq': functools.partial(<function written_bytes>, <function \_to_gbq_unavailable>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'h5': functools.partial(<function written_bytes>, <function NDFrame.to_hdf>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'hdf5': functools.partial(<function written_bytes>, <function NDFrame.to_hdf>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'html': functools.partial(<function written_bytes>, functools.partial(<function DataFrame.to_html>, index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'json': functools.partial(<function written_bytes>, <function NDFrame.to_json>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'npy': functools.partial(<function written_bytes>, <function save>, obj_arg_position_in_writer=1, io_buffer_cls=<class '_io.BytesIO'>), 'orc': functools.partial(<function written_bytes>, <function DataFrame.to_orc>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'p': functools.partial(<function written_bytes>, <function NDFrame.to_pickle>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'parquet': functools.partial(<function written_bytes>, <function cast_to_parquet>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'pickle': functools.partial(<function written_bytes>, <function NDFrame.to_pickle>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'pkl': functools.partial(<function written_bytes>, <function NDFrame.to_pickle>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'sql': functools.partial(<function written_bytes>, <function NDFrame.to_sql>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'sqlite': functools.partial(<function written_bytes>, <function NDFrame.to_sql>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'stata': functools.partial(<function written_bytes>, functools.partial(<function DataFrame.to_stata>, write_index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'tsv': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_csv>, index=False, sep='\\\\t', escapechar='\\\\\\\\', quotechar='"'), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'txt': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_csv>, index=False), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'xls': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_excel>, index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'xlsx': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_excel>, index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'xml': functools.partial(<function written_bytes>, <function DataFrame.to_xml>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'zip': <function save_df_to_zipped_tsv>}, extension_decoder_mapping={'arrow': functools.partial(<function read_from_bytes>, <function arrow_bytes_to_dataframe>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'csv': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'dta': functools.partial(<function read_from_bytes>, functools.partial(<function read_stata>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'feather': functools.partial(<function read_from_bytes>, <function read_feather>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'h5': functools.partial(<function read_from_bytes>, <function read_hdf>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'hdf5': functools.partial(<function read_from_bytes>, <function read_hdf>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'html': functools.partial(<function read_from_bytes>, functools.partial(<function read_html>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'json': functools.partial(<function read_from_bytes>, functools.partial(<function read_json>, orient='records'), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'orc': functools.partial(<function read_from_bytes>, <function read_orc>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'p': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'parquet': functools.partial(<function read_from_bytes>, <function read_parquet>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'pickle': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'pkl': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sas': functools.partial(<function read_from_bytes>, <function read_sas>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sav': functools.partial(<function read_from_bytes>, <function read_spss>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sql': functools.partial(<function read_from_bytes>, <function read_sql>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sqlite': functools.partial(<function read_from_bytes>, <function read_sql>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'stata': functools.partial(<function read_from_bytes>, functools.partial(<function read_stata>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'tsv': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, sep='\\\\t', index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'txt': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xls': functools.partial(<function read_from_bytes>, functools.partial(<function read_excel>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xlsx': functools.partial(<function read_from_bytes>, functools.partial(<function read_excel>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xml': functools.partial(<function read_from_bytes>, <function read_xml>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>)}, extra_encoder_kwargs=(), extra_decoder_kwargs=(), allow_writing_bytes=True, sqlite_tables=None, sqlite_verbose=False)

Bases: `Files`

A key-value store providing values as pandas.DataFrames.

Use Case: You have a bunch of files in a folder, all corresponding to some
dataframes that were saved in some way. You want to a key-value store whose values
are the (decoded) dataframes corresponding to the files in the folder.

Additionally, if you provide a SQLite database file instead of a directory,
it will automatically extract the tables as parquet files in a temporary directory
and provide access to them as DataFrames.

* **Parameters:**
  * **rootdir** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – A root directory or a SQLite database file.
  * **extension_encoder_mapping** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`Extension`), [`Callable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)[[[`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`Obj`)], `DataFrame`]]) – A mapping from file extensions to functions that
    encode a DataFrame to bytes for writing.
  * **extension_decoder_mapping** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`Extension`), [`Callable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)[[[`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`Obj`)], `DataFrame`]]) – A mapping from file extensions to functions that can
    read the dataframes
  * **extra_encoder_kwargs** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict) | [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)) – Extra arguments to pass to the encoder functions.
  * **extra_decoder_kwargs** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict) | [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)) – Extra arguments to pass to the decoder functions.
  * **allow_writing_bytes** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, values that are already `bytes` can be written
    as-is; if False, writing raw bytes raises a `ValueError`.
  * **sqlite_tables** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`Sequence`](https://docs.python.org/3/library/typing.html#typing.Sequence)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]) – When `rootdir` is a SQLite database file, the table names to
    export (all tables, if None).
  * **sqlite_verbose** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – When `rootdir` is a SQLite database file, whether to print
    progress while exporting its tables.

#### *classmethod* from_sqlite_file(sqlite_file, , tables=None, verbose=False, \*\*kwargs)

Create a DfFiles instance from a SQLite database file.

This method exports all tables from the SQLite database to parquet files
in a temporary directory and returns a DfFiles instance that provides
access to these tables as DataFrames.

* **Parameters:**
  * **sqlite_file** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Path to the SQLite database file
  * **tables** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`Sequence`](https://docs.python.org/3/library/typing.html#typing.Sequence)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]) – Optional list of table names to export. If None, exports all tables.
  * **verbose** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to print progress information
  * **\*\*kwargs** – Additional arguments passed to the DfFiles constructor
* **Return type:**
  [`DfFiles`](_autosummary/tabled.base.html.md#tabled.base.DfFiles)
* **Returns:**
  A DfFiles instance providing access to the SQLite tables as DataFrames
* **Raises:**
  * [**FileNotFoundError**](https://docs.python.org/3/builtins/exceptions.html#FileNotFoundError) – If `sqlite_file` does not exist.
  * [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If `sqlite_file` does not look like a SQLite database.

### tabled.base.DfLocalFileReader

alias of [`DfReader`](_autosummary/tabled.base.html.md#tabled.base.DfReader)

### *class* tabled.base.DfReader(rootdir, \*, extension_encoder_mapping={'arrow': functools.partial(<function written_bytes>, <function dataframe_to_arrow_bytes>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'csv': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_csv>, index=False), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'dta': functools.partial(<function written_bytes>, functools.partial(<function DataFrame.to_stata>, write_index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'feather': functools.partial(<function written_bytes>, <function DataFrame.to_feather>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'gbq': functools.partial(<function written_bytes>, <function \_to_gbq_unavailable>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'h5': functools.partial(<function written_bytes>, <function NDFrame.to_hdf>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'hdf5': functools.partial(<function written_bytes>, <function NDFrame.to_hdf>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'html': functools.partial(<function written_bytes>, functools.partial(<function DataFrame.to_html>, index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'json': functools.partial(<function written_bytes>, <function NDFrame.to_json>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'npy': functools.partial(<function written_bytes>, <function save>, obj_arg_position_in_writer=1, io_buffer_cls=<class '_io.BytesIO'>), 'orc': functools.partial(<function written_bytes>, <function DataFrame.to_orc>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'p': functools.partial(<function written_bytes>, <function NDFrame.to_pickle>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'parquet': functools.partial(<function written_bytes>, <function cast_to_parquet>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'pickle': functools.partial(<function written_bytes>, <function NDFrame.to_pickle>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'pkl': functools.partial(<function written_bytes>, <function NDFrame.to_pickle>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'sql': functools.partial(<function written_bytes>, <function NDFrame.to_sql>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'sqlite': functools.partial(<function written_bytes>, <function NDFrame.to_sql>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'stata': functools.partial(<function written_bytes>, functools.partial(<function DataFrame.to_stata>, write_index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'tsv': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_csv>, index=False, sep='\\\\t', escapechar='\\\\\\\\', quotechar='"'), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'txt': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_csv>, index=False), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'xls': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_excel>, index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'xlsx': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_excel>, index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'xml': functools.partial(<function written_bytes>, <function DataFrame.to_xml>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'zip': <function save_df_to_zipped_tsv>}, extension_decoder_mapping={'arrow': functools.partial(<function read_from_bytes>, <function arrow_bytes_to_dataframe>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'csv': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'dta': functools.partial(<function read_from_bytes>, functools.partial(<function read_stata>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'feather': functools.partial(<function read_from_bytes>, <function read_feather>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'h5': functools.partial(<function read_from_bytes>, <function read_hdf>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'hdf5': functools.partial(<function read_from_bytes>, <function read_hdf>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'html': functools.partial(<function read_from_bytes>, functools.partial(<function read_html>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'json': functools.partial(<function read_from_bytes>, functools.partial(<function read_json>, orient='records'), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'orc': functools.partial(<function read_from_bytes>, <function read_orc>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'p': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'parquet': functools.partial(<function read_from_bytes>, <function read_parquet>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'pickle': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'pkl': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sas': functools.partial(<function read_from_bytes>, <function read_sas>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sav': functools.partial(<function read_from_bytes>, <function read_spss>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sql': functools.partial(<function read_from_bytes>, <function read_sql>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sqlite': functools.partial(<function read_from_bytes>, <function read_sql>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'stata': functools.partial(<function read_from_bytes>, functools.partial(<function read_stata>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'tsv': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, sep='\\\\t', index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'txt': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xls': functools.partial(<function read_from_bytes>, functools.partial(<function read_excel>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xlsx': functools.partial(<function read_from_bytes>, functools.partial(<function read_excel>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xml': functools.partial(<function read_from_bytes>, <function read_xml>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>)}, extra_encoder_kwargs=(), extra_decoder_kwargs=(), allow_writing_bytes=True, sqlite_tables=None, sqlite_verbose=False)

Bases: [`DfFiles`](_autosummary/tabled.base.html.md#tabled.base.DfFiles)

A read-only `DfFiles`: writes and deletes raise `NotImplementedError`.

### *class* tabled.base.KeyFuncReader(mapping, key=<function identity>)

Bases: `KvReader`

A read-only mapping view that transforms keys before lookup in `mapping`.

Iteration and length reflect `mapping` as-is; `__getitem__` and
`__contains__` apply `key` to the given key first.

### tabled.base.convert_collection_to_dataframe_if_possible(x)

Return `x` as a DataFrame if it is a dict, list, tuple, Series or Index; else `x` unchanged.

### tabled.base.get_table(table_src=None, \*, ext=None, ext_mapping={'arrow': functools.partial(<function read_from_bytes>, <function arrow_bytes_to_dataframe>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'csv': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'dta': functools.partial(<function read_from_bytes>, functools.partial(<function read_stata>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'feather': functools.partial(<function read_from_bytes>, <function read_feather>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'h5': functools.partial(<function read_from_bytes>, <function read_hdf>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'hdf5': functools.partial(<function read_from_bytes>, <function read_hdf>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'html': functools.partial(<function read_from_bytes>, functools.partial(<function read_html>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'json': functools.partial(<function read_from_bytes>, functools.partial(<function read_json>, orient='records'), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'orc': functools.partial(<function read_from_bytes>, <function read_orc>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'p': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'parquet': functools.partial(<function read_from_bytes>, <function read_parquet>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'pickle': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'pkl': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sas': functools.partial(<function read_from_bytes>, <function read_sas>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sav': functools.partial(<function read_from_bytes>, <function read_spss>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sql': functools.partial(<function read_from_bytes>, <function read_sql>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sqlite': functools.partial(<function read_from_bytes>, <function read_sql>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'stata': functools.partial(<function read_from_bytes>, functools.partial(<function read_stata>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'tsv': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, sep='\\\\t', index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'txt': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xls': functools.partial(<function read_from_bytes>, functools.partial(<function read_excel>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xlsx': functools.partial(<function read_from_bytes>, functools.partial(<function read_excel>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xml': functools.partial(<function read_from_bytes>, <function read_xml>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>)}, resolve_to_io=<function default_io_resolver>, \*\*extra_decoder_kwargs)

Get a table from a variety of sources.

* **Return type:**
  `DataFrame`

### tabled.base.validate_fields(df, key_fields, value_columns)

Raise `ValueError` if any `key_fields` or `value_columns` are missing from `df`.


# _autosummary/tabled.coerce.html.md

# tabled.coerce

Column type coercion utilities for pandas DataFrames.

This module provides tools for conditionally transforming DataFrame columns
based on sampled value inspection. The primary use case is detecting and
converting columns that contain serialized data (e.g., JSON strings that
should be lists or dicts).

The design follows a sample-then-transform pattern:

1. Sample a subset of non-null values from a column
2. Test if a condition holds for a threshold fraction of samples
3. If so, apply a transformation to all non-null values

This approach is efficient for large DataFrames where checking every value
would be expensive, and robust to mixed or partially malformed data.

### Example

```pycon
>>> import pandas as pd
>>> from tabled.coerce import coerce_json_list_column
>>>
>>> # A column with JSON list strings
>>> s = pd.Series(['[1, 2, 3]', '["a", "b"]', None, '[4, 5]'])
>>> coerced = coerce_json_list_column(s)
>>> coerced.iloc[0]
[1, 2, 3]
>>> coerced.iloc[1]
['a', 'b']
```

### Functions

| [`coerce_dataframe_columns`](_autosummary/tabled.coerce.html.md#tabled.coerce.coerce_dataframe_columns)(df, condition, ...)    | Conditionally coerce columns in a DataFrame.                        |
|--------------------------------------------------------------------------------------------------|---------------------------------------------------------------------|
| [`coerce_json_column`](_autosummary/tabled.coerce.html.md#tabled.coerce.coerce_json_column)(series, \*\*kwargs)          | Coerce a column of JSON strings to Python objects.                  |
| [`coerce_json_columns`](_autosummary/tabled.coerce.html.md#tabled.coerce.coerce_json_columns)(df[, columns, verbose])     | Coerce JSON string columns in a DataFrame to Python objects.        |
| [`coerce_json_list_column`](_autosummary/tabled.coerce.html.md#tabled.coerce.coerce_json_list_column)(series, \*\*kwargs)     | Coerce a column of JSON list strings to Python lists.               |
| [`coerce_series_conditionally`](_autosummary/tabled.coerce.html.md#tabled.coerce.coerce_series_conditionally)(series, ...[, ...]) | Conditionally transform a pandas Series based on sampled values.    |
| [`is_json_dict_string`](_autosummary/tabled.coerce.html.md#tabled.coerce.is_json_dict_string)(value)                      | Check if a value looks like a JSON object/dict encoded as a string. |
| [`is_json_list_string`](_autosummary/tabled.coerce.html.md#tabled.coerce.is_json_list_string)(value)                      | Check if a value looks like a JSON list encoded as a string.        |
| [`is_json_string`](_autosummary/tabled.coerce.html.md#tabled.coerce.is_json_string)(value)                           | Check if a value looks like a JSON-encoded string.                  |
| [`parse_json_safe`](_autosummary/tabled.coerce.html.md#tabled.coerce.parse_json_safe)(value)                          | Parse a JSON string, returning the original value if parsing fails. |

### tabled.coerce.coerce_dataframe_columns(df, condition, transform, columns=None, , sample_size=100, threshold=0.8, verbose=False)

Conditionally coerce columns in a DataFrame.

Applies coerce_series_conditionally to specified columns (or all
object-dtype columns if none specified).

* **Parameters:**
  * **df** (`DataFrame`) – The DataFrame to process.
  * **condition** ([`Callable`](https://docs.python.org/3/library/typing.html#typing.Callable)) – A function (value -> bool) to test if values need transformation.
  * **transform** ([`Callable`](https://docs.python.org/3/library/typing.html#typing.Callable)) – A function (value -> new_value) to apply to matching values.
  * **columns** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`List`](https://docs.python.org/3/library/typing.html#typing.List)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]) – Specific columns to check. If None, checks all object-dtype columns.
  * **sample_size** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum number of values to sample per column.
  * **threshold** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Fraction of samples that must satisfy condition to trigger transform.
  * **verbose** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, print which columns were transformed.
* **Returns:**
  DataFrame with coerced columns.
* **Return type:**
  `DataFrame`

### Examples

```pycon
>>> import pandas as pd
>>> df = pd.DataFrame({
...     'json_col': ['[1]', '[2]', '[3]'],
...     'text_col': ['a', 'b', 'c']
... })
>>> from tabled.coerce import is_json_list_string, parse_json_safe
>>> result = coerce_dataframe_columns(
...     df, is_json_list_string, parse_json_safe
... )
>>> result['json_col'].iloc[0]
[1]
>>> result['text_col'].iloc[0]  # unchanged - not a JSON list
'a'
```

### tabled.coerce.coerce_json_column(series, \*\*kwargs)

Coerce a column of JSON strings to Python objects.

Detects and converts strings that contain JSON arrays or objects
to their Python equivalents (lists or dicts).

* **Parameters:**
  * **series** (`Series`) – The series to coerce.
  * **\*\*kwargs** – Additional arguments passed to coerce_series_conditionally
    (sample_size, threshold).
* **Returns:**
  Series with JSON strings converted to Python objects.
* **Return type:**
  `Series`

### Examples

```pycon
>>> import pandas as pd
>>> s = pd.Series(['[1, 2]', '{"a": 1}', 'text', None])
>>> # Note: won't transform if < 80% are JSON by default
>>> s_homogeneous = pd.Series(['[1]', '[2]', '[3]', None])
>>> coerced = coerce_json_column(s_homogeneous)
>>> coerced.iloc[0]
[1]
```

### tabled.coerce.coerce_json_columns(df, columns=None, , verbose=False, \*\*kwargs)

Coerce JSON string columns in a DataFrame to Python objects.

A convenience function that applies JSON coercion to specified columns
(or all object-dtype columns) in a DataFrame.

* **Parameters:**
  * **df** (`DataFrame`) – The DataFrame to process.
  * **columns** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`List`](https://docs.python.org/3/library/typing.html#typing.List)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]) – Specific columns to check. If None, checks all object-dtype columns.
  * **verbose** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, print which columns were transformed.
  * **\*\*kwargs** – Additional arguments passed to coerce_series_conditionally
    (sample_size, threshold).
* **Returns:**
  DataFrame with JSON string columns coerced to Python objects.
* **Return type:**
  `DataFrame`

### Examples

```pycon
>>> import pandas as pd
>>> df = pd.DataFrame({
...     'tags': ['["a", "b"]', '["c"]', '["d", "e", "f"]'],
...     'ids': ['[1, 2]', '[3]', '[4, 5]'],
...     'name': ['Alice', 'Bob', 'Charlie']
... })
>>> result = coerce_json_columns(df)
>>> result['tags'].iloc[0]
['a', 'b']
>>> result['name'].iloc[0]  # Unchanged - not JSON
'Alice'
```

### tabled.coerce.coerce_json_list_column(series, \*\*kwargs)

Coerce a column of JSON list strings to Python lists.

This is a convenience wrapper around coerce_series_conditionally
configured for the common case of columns containing JSON list strings.

* **Parameters:**
  * **series** (`Series`) – The series to coerce.
  * **\*\*kwargs** – Additional arguments passed to coerce_series_conditionally
    (sample_size, threshold).
* **Returns:**
  Series with JSON list strings converted to Python lists.
* **Return type:**
  `Series`

### Examples

```pycon
>>> import pandas as pd
>>> s = pd.Series(['[1, 2, 3]', '["a", "b"]', None])
>>> coerced = coerce_json_list_column(s)
>>> coerced.iloc[0]
[1, 2, 3]
>>> coerced.iloc[1]
['a', 'b']
```

### tabled.coerce.coerce_series_conditionally(series, condition, transform, , sample_size=100, threshold=0.8)

Conditionally transform a pandas Series based on sampled values.

This function samples non-null values to check if a condition holds,
and if so, applies the transform to all non-null values. This is useful
for efficiently detecting and converting columns with serialized data.

* **Parameters:**
  * **series** (`Series`) – The series to potentially transform.
  * **condition** ([`Callable`](https://docs.python.org/3/library/typing.html#typing.Callable)) – A function (value -> bool) that tests whether a value needs
    transformation. Applied to a sample to determine if transformation
    should occur for the whole series.
  * **transform** ([`Callable`](https://docs.python.org/3/library/typing.html#typing.Callable)) – A function (value -> new_value) to apply to each non-null value
    if the condition threshold is met.
  * **sample_size** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum number of non-null values to sample for condition testing.
    Larger samples give more reliable detection but cost more time.
  * **threshold** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Fraction of sampled values that must satisfy the condition (0.0 to 1.0)
    for the transform to be applied. Use lower values for columns with
    mixed or partially valid data.
* **Returns:**
  The original series if condition not met, otherwise a new series
  with transformed values (null values are preserved).
* **Return type:**
  `Series`

### Examples

```pycon
>>> import pandas as pd
>>> s = pd.Series(['[1, 2]', '[3, 4]', None, '[5]'])
>>> is_json_list = lambda x: isinstance(x, str) and x.startswith('[')
>>> import json
>>> result = coerce_series_conditionally(s, is_json_list, json.loads)
>>> result.iloc[0]
[1, 2]
>>> pd.isna(result.iloc[2])  # null values are preserved (None or NaN)
True
```

### Notes

The function uses a fixed random_state (42) for reproducible sampling.
If the series has fewer non-null values than sample_size, all non-null
values are used for testing.

### tabled.coerce.is_json_dict_string(value)

Check if a value looks like a JSON object/dict encoded as a string.

* **Parameters:**
  **value** (*any*) – The value to check.
* **Returns:**
  True if the value appears to be a JSON object string.
* **Return type:**
  [`bool`](https://docs.python.org/3/builtins/functions.html#bool)

### Examples

```pycon
>>> is_json_dict_string('{"key": "value"}')
True
>>> is_json_dict_string('[1, 2, 3]')
False
```

### tabled.coerce.is_json_list_string(value)

Check if a value looks like a JSON list encoded as a string.

* **Parameters:**
  **value** (*any*) – The value to check.
* **Returns:**
  True if the value appears to be a JSON list string.
* **Return type:**
  [`bool`](https://docs.python.org/3/builtins/functions.html#bool)

### Examples

```pycon
>>> is_json_list_string('[1, 2, 3]')
True
>>> is_json_list_string('["a", "b"]')
True
>>> is_json_list_string('{"key": "value"}')
False
>>> is_json_list_string('not json')
False
```

### tabled.coerce.is_json_string(value)

Check if a value looks like a JSON-encoded string.

Detects strings that appear to contain JSON arrays or objects
(starting with ‘[’ or ‘{’ and ending with ‘]’ or ‘}’).

* **Parameters:**
  **value** (*any*) – The value to check.
* **Returns:**
  True if the value appears to be a JSON string.
* **Return type:**
  [`bool`](https://docs.python.org/3/builtins/functions.html#bool)

### Examples

```pycon
>>> is_json_string('[1, 2, 3]')
True
>>> is_json_string('{"key": "value"}')
True
>>> is_json_string('plain text')
False
>>> is_json_string(123)
False
```

### tabled.coerce.parse_json_safe(value)

Parse a JSON string, returning the original value if parsing fails.

This is a safe wrapper around json.loads that never raises exceptions,
making it suitable for use with coerce_series_conditionally on columns
that may contain some malformed JSON.

* **Parameters:**
  **value** (*any*) – The value to parse. If not a valid JSON string, returned as-is.
* **Returns:**
  The parsed JSON value, or the original value if parsing failed.
* **Return type:**
  any

### Examples

```pycon
>>> parse_json_safe('[1, 2, 3]')
[1, 2, 3]
>>> parse_json_safe('{"a": 1}')
{'a': 1}
>>> parse_json_safe('not json')
'not json'
>>> parse_json_safe(None)  # Non-strings pass through
```


# _autosummary/tabled.compare_tables.html.md

# tabled.compare_tables

Tools to compare tables

### Functions

| [`columns_diff`](_autosummary/tabled.compare_tables.html.md#tabled.compare_tables.columns_diff)(df1, df2)                        | Return columns that are not common between df1 and df2.                   |
|------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------|
| [`columns_value_diff`](_autosummary/tabled.compare_tables.html.md#tabled.compare_tables.columns_value_diff)(df1, df2)                  | For each column present in both dataframes, compare the values row-wise.  |
| [`dataframe_diffs`](_autosummary/tabled.compare_tables.html.md#tabled.compare_tables.dataframe_diffs)(df1, df2[, comparisons, ...]) | Compare the diff of dataframes using specified diff comparison functions. |
| [`dtypes_diff`](_autosummary/tabled.compare_tables.html.md#tabled.compare_tables.dtypes_diff)(df1, df2)                         | Return columns where the data types differ between df1 and df2.           |
| [`ensure_comparisons_dict`](_autosummary/tabled.compare_tables.html.md#tabled.compare_tables.ensure_comparisons_dict)(comparisons)          | Ensure that the comparisons are in the form of a dictionary.              |
| [`index_diff`](_autosummary/tabled.compare_tables.html.md#tabled.compare_tables.index_diff)(df1, df2)                          | Return indices that are not common between df1 and df2.                   |
| [`shape_diff`](_autosummary/tabled.compare_tables.html.md#tabled.compare_tables.shape_diff)(df1, df2)                          | Return the shapes of df1 and df2 if they differ.                          |

### Classes

| [`BinaryFuncResult`](_autosummary/tabled.compare_tables.html.md#tabled.compare_tables.BinaryFuncResult)   | A `{left_right, right_left}` dict, truthy if either value is truthy.   |
|---------------------------------------------------------------------|------------------------------------------------------------------------|

### Exceptions

| [`InvalidComparison`](_autosummary/tabled.compare_tables.html.md#tabled.compare_tables.InvalidComparison)   | Raised or returned when a comparison that was asked for is not applicable to the dataframes in question   |
|----------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------|

### *class* tabled.compare_tables.BinaryFuncResult

Bases: [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)

A `{left_right, right_left}` dict, truthy if either value is truthy.

#### *classmethod* from_func(func, x, y)

Build a `BinaryFuncResult` from `func(x, y)` and `func(y, x)`.

### *exception* tabled.compare_tables.InvalidComparison

Bases: [`ValueError`](https://docs.python.org/3/builtins/exceptions.html#ValueError)

Raised or returned when a comparison that was asked for is not applicable to the dataframes in question

### tabled.compare_tables.columns_diff(df1, df2)

Return columns that are not common between df1 and df2.

### tabled.compare_tables.columns_value_diff(df1, df2)

For each column present in both dataframes, compare the values row-wise.
Returns a dict with column names as keys and DataFrames of differences as values.
Only columns with differences are included.

### tabled.compare_tables.dataframe_diffs(df1, df2, comparisons={'columns_diff': <function columns_diff>, 'columns_value_diff': <function columns_value_diff>, 'dtypes_diff': <function dtypes_diff>, 'index_diff': <function index_diff>, 'shape_diff': <function shape_diff>}, \*, diff_condition=<class 'bool'>)

Compare the diff of dataframes using specified diff comparison functions.

Returns a dictionary with comparison names as keys and comparison results as values.

* **Parameters:**
  * **df1** (`DataFrame`) – The first dataframe to compare.
  * **df2** (`DataFrame`) – The second dataframe to compare.
  * **comparisons** (`Union`[[`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Callable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)[[`DataFrame`, `DataFrame`], [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]], [`Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence)[`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Callable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)[[`DataFrame`, `DataFrame`], [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]]], [`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Callable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)[[`DataFrame`, `DataFrame`], [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]]) – A dictionary or list of comparison functions or names.
    Defaults to DFLT_COMPARISONS.
  * **diff_condition** (*callable*) – A function that determines whether to include a comparison result
    in the output dictionary based on the comparison result.
    Defaults to the built-in `bool` function.
* **Returns:**
  A dictionary with comparison names as keys and comparison results as values.
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)

### Example

```pycon
>>> import pandas as pd
>>> df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]}, index=[0, 1])
>>> df2 = pd.DataFrame({'A': [1, 2], 'C': [5, 6]}, index=[1, 2])
>>> diffs = dataframe_diffs(df1, df2)
>>> diffs
{'columns_diff': {'left_right': {'B'}, 'right_left': {'C'}},
 'index_diff': {'left_right': {0}, 'right_left': {2}},
 'columns_value_diff': {'A':    left  right
1     2      1}}
```

### tabled.compare_tables.dtypes_diff(df1, df2)

Return columns where the data types differ between df1 and df2.

### tabled.compare_tables.ensure_comparisons_dict(comparisons)

Ensure that the comparisons are in the form of a dictionary.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Callable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)[[`DataFrame`, `DataFrame`], [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]]

### tabled.compare_tables.index_diff(df1, df2)

Return indices that are not common between df1 and df2.

### tabled.compare_tables.shape_diff(df1, df2)

Return the shapes of df1 and df2 if they differ.


# _autosummary/tabled.diagnose.html.md

# tabled.diagnose

DataFrame and table collection diagnosis utilities.

This module provides flexible tools for analyzing pandas DataFrames and collections
of tables. The core function `dataframe_info` extracts configurable information
from DataFrames using pluggable info functions.

Key Features:

- Configurable info extraction with `dataframe_info`
- Collection diagnosis with `diagnose_table_collection`
- Extensible via custom info functions
- Backward-compatible `print_dataframe_info` from cosmodata

### Example

```pycon
>>> import pandas as pd
>>> df = pd.DataFrame({'a': [1, 2, 3], 'b': ['x', 'y', 'z']})
>>> info = dataframe_info(df)
>>> info['shape']
(3, 2)
```

### Register custom info function

```pycon
>>> def get_memory_usage(df):
...     return df.memory_usage(deep=True).sum()
>>> register_info_func('custom_memory', get_memory_usage)
```

### Functions

| [`dataframe_info`](_autosummary/tabled.diagnose.html.md#tabled.diagnose.dataframe_info)(df[, info_funcs, egress])         | Extract information from a DataFrame using specified info functions.        |
|---------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------|
| [`list_info_funcs`](_autosummary/tabled.diagnose.html.md#tabled.diagnose.list_info_funcs)()                                | List all registered info function names.                                    |
| [`print_dataframe_info`](_autosummary/tabled.diagnose.html.md#tabled.diagnose.print_dataframe_info)(df[, exclude_columns, ...]) | Print information about a DataFrame.                                        |
| [`register_info_func`](_autosummary/tabled.diagnose.html.md#tabled.diagnose.register_info_func)(name, func, \*[, overwrite])  | Register a new info function in the default info functions dictionary.      |
| [`scalar_columns`](_autosummary/tabled.diagnose.html.md#tabled.diagnose.scalar_columns)(df)                               | Returns the list of columns that are scalar (therefore serializable to CSV) |

### tabled.diagnose.dataframe_info(df, info_funcs={'categorical_stats': <function \_get_categorical_stats>, 'columns': <function \_get_columns>, 'first_row': <function \_get_first_row>, 'numeric_stats': <function \_get_numeric_stats>, 'sample_rows': <function \_get_sample_rows>, 'shape': <function \_get_shape>}, \*, egress=<class 'dict'>)

Extract information from a DataFrame using specified info functions.

* **Parameters:**
  * **df** (`DataFrame`) – The DataFrame to analyze
  * **info_funcs** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Callable`](https://docs.python.org/3/library/typing.html#typing.Callable)]) – Dict mapping info keys to functions that take a DataFrame
  * **egress** ([`Callable`](https://docs.python.org/3/library/typing.html#typing.Callable)) – Function to process the generator of (key, value) pairs
* **Returns:**
  Result of egress applied to the info generator

```pycon
>>> import pandas as pd
>>> df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
>>> info = dataframe_info(df, {'shape': _get_shape})
>>> info['shape']
(3, 2)
```

### tabled.diagnose.list_info_funcs()

List all registered info function names.

* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]

### tabled.diagnose.print_dataframe_info(df, exclude_columns=(), \*, mode='short', egress=<built-in function print>)

Print information about a DataFrame.

* **Parameters:**
  * **df** (`DataFrame`) – The DataFrame to analyze
  * **exclude_columns** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]) – Columns to exclude from analysis
  * **mode** ([`Literal`](https://docs.python.org/3/library/typing.html#typing.Literal)[`'short'`, `'sample'`, `'stats'`]) – 

    Type of information to display
    - ’short’: shape and first row
    - ’sample’: shape, columns, and random rows
    - ’stats’: descriptive statistics
  * **egress** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`Callable`](https://docs.python.org/3/library/typing.html#typing.Callable)[[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)], [`None`](https://docs.python.org/3/builtins/constants.html#None)]]) – Callback function for output (None returns string instead of printing)
* **Returns:**
  The formatted info string when `egress` is `None` or falsy; otherwise
  the result of calling `egress` on that string.
* **Raises:**
  [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If `mode` is not one of `'short'`, `'sample'`, `'stats'`.

```pycon
>>> import pandas as pd
>>> df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
>>> info = print_dataframe_info(df, egress=None)
>>> 'shape: (3, 2)' in info
True
```

### tabled.diagnose.register_info_func(name, func, , overwrite=False)

Register a new info function in the default info functions dictionary.

* **Parameters:**
  * **name** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Name for the info function
  * **func** ([`Callable`](https://docs.python.org/3/library/typing.html#typing.Callable)[[`DataFrame`], `any`]) – Function that takes a DataFrame and returns info
  * **overwrite** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to overwrite existing functions with the same name
* **Raises:**
  [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If `name` is already registered and `overwrite` is `False`.

### Example

```pycon
>>> def get_memory_usage(df):
...     return df.memory_usage(deep=True).sum()
>>> register_info_func('test_memory', get_memory_usage)
```

### tabled.diagnose.scalar_columns(df)

Returns the list of columns that are scalar (therefore serializable to CSV)

More precisely, this function returns the list of columns that contain only
scalar values (e.g., int, float, str, bool, etc.) and can be saved to a CSV
file.

* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)

### Example

```pycon
>>> import pandas as pd
>>> df = pd.DataFrame({
...     'A': [1, 2, 3],
...     'B': ['x', 'y', 'z'],
...     'C': [{'a': 1}, {'b': 2}, {'c': 3}],  # Non-serializable column
...     'D': [[1, 2], [3, 4], [5, 6]]         # Non-serializable column
... })
>>> scalar_columns(df)
['A', 'B']
```


# _autosummary/tabled.html.html.md

# tabled.html

To work with html

### Functions

| [`df_store_to_html`](_autosummary/tabled.html.html.md#tabled.html.df_store_to_html)(df_store[, sep])                | Render each dataframe in `df_store`, titled by its key's leading non-digit prefix, joined by `sep`.   |
|---------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------|
| [`df_to_html`](_autosummary/tabled.html.html.md#tabled.html.df_to_html)(df[, title])                          | Render `df` as an HTML table, with an optional `<h2>` title above it.                                 |
| [`dfs_to_html_pretty`](_autosummary/tabled.html.html.md#tabled.html.dfs_to_html_pretty)(dfs[, title])                 | Write an entire dataframe to an HTML file with nice formatting.                                       |
| [`dfs_to_pdf_bytes`](_autosummary/tabled.html.html.md#tabled.html.dfs_to_pdf_bytes)(dfs[, title])                   | Render `dfs` (a DataFrame, a mapping, or an iterable of DataFrames) to PDF bytes.                     |
| [`get_tables_from_url`](_autosummary/tabled.html.html.md#tabled.html.get_tables_from_url)(url, \*[, url_to_html, ...]) | Get's a list of pandas dataframes from tables scraped from a url.                                     |
| [`url_to_html_func`](_autosummary/tabled.html.html.md#tabled.html.url_to_html_func)([kind])                         | Get a url_to_html function of a given kind.                                                           |

### tabled.html.df_store_to_html(df_store, sep='\\n<br>\\n')

Render each dataframe in `df_store`, titled by its key’s leading non-digit prefix, joined by `sep`.

### tabled.html.df_to_html(df, title=None)

Render `df` as an HTML table, with an optional `<h2>` title above it.

### tabled.html.dfs_to_html_pretty(dfs, title=None)

Write an entire dataframe to an HTML file
with nice formatting.
Thanks to @stackoverflowuser2010 for the
pretty printer see [https://stackoverflow.com/a/47723330/362951](https://stackoverflow.com/a/47723330/362951)

### tabled.html.dfs_to_pdf_bytes(dfs, title=None)

Render `dfs` (a DataFrame, a mapping, or an iterable of DataFrames) to PDF bytes.

Requires the optional `weasyprint` dependency.

### tabled.html.get_tables_from_url(url, , url_to_html='requests', filt=None, encoding='utf-8', \*\*tables_from_html_kwargs)

Get’s a list of pandas dataframes from tables scraped from a url.
Note that this will only work with static pages. If the html needs to be rendered dynamically,
you’ll have to get your needed html otherwise (like with selenium).

```pycon
>>> url = 'https://en.wikipedia.org/wiki/List_of_musical_instruments'
>>> tables = get_tables_from_url(url)
```

If you install selenium and download a chromedriver,
you can even use your browser to render dynamic html.
Say, to get updated coronavirus stats without a need to figure out the API
(I mean, why have to figure out the language of an API, when someone already did that
for you in their webpage!!):

```python
url = 'https://www.worldometers.info/coronavirus/?utm_campaign=homeAdvegas1?'
tables = get_tables_from_url(url, url_to_html='chrome')  # doctest: +SKIP
```

To make selenium work:

- `pip install selenium`
- Download seleniumdriver here: [https://chromedriver.chromium.org/](https://chromedriver.chromium.org/)
- Uzip and put in a place that’s on you PATH (run command `echo $PATH` for a list of those places)

### tabled.html.url_to_html_func(kind='requests')

Get a url_to_html function of a given kind.

* **Return type:**
  [`Callable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)


# _autosummary/tabled.html.md

# tabled

A data-object-layer package for accessing pandas DataFrames from various sources.

This package provides a unified interface for reading, writing, and manipulating
tabular data from multiple sources including files, URLs, and custom data stores.
It offers flexible key-value mapping functionality where keys can represent file
paths, URLs, or other identifiers, and values are pandas DataFrames.

Key Features:

- Read tables from URLs, HTML pages, and various file formats
- Store abstraction (DfFiles) for mapping keys to DataFrames
- Extension-based encoding/decoding for different file formats
- Column-oriented data manipulation utilities
- DataFrame comparison and diff functionality
- JSON serialization support for pandas objects
- Row/column expansion and collapse operations
- Duplicate detection and handling

Main Components:

- HTML table extraction from web pages
- File-based DataFrame storage with automatic format detection
- Multi-source data readers with customizable key functions
- Utility functions for DataFrame manipulation and analysis
- Codec system for handling different data formats
- Comparison tools for analyzing differences between tables

The package is designed to simplify data pipeline workflows where tabular data
needs to be accessed from heterogeneous sources and processed in a consistent manner.

### Modules

| [`base`](_autosummary/tabled.base.html.md#module-tabled.base)                     | Based functionality for tabled                                                   |
|----------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------|
| [`coerce`](_autosummary/tabled.coerce.html.md#module-tabled.coerce)                 | Column type coercion utilities for pandas DataFrames.                            |
| [`compare_tables`](_autosummary/tabled.compare_tables.html.md#module-tabled.compare_tables) | Tools to compare tables                                                          |
| [`diagnose`](_autosummary/tabled.diagnose.html.md#module-tabled.diagnose)             | DataFrame and table collection diagnosis utilities.                              |
| [`html`](_autosummary/tabled.html.html.md#module-tabled.html)                     | To work with html                                                                |
| [`join_tables`](_autosummary/tabled.join_tables.html.md#module-tabled.join_tables)       | Join multiple tables (pandas DataFrames) down to a target subset of columns.     |
| [`misc`](_autosummary/tabled.misc.html.md#module-tabled.misc)                     | Miscellaneous utility functions for tables.                                      |
| [`multi`](_autosummary/tabled.multi.html.md#module-tabled.multi)                   | Multi-tabled data structures.                                                    |
| [`sqlite_tools`](_autosummary/tabled.sqlite_tools.html.md#module-tabled.sqlite_tools)     | General-purpose SQLite to DataFrame/Parquet export tools using DuckDB.           |
| [`tools`](_autosummary/tabled.tools.html.md#module-tabled.tools)                   | Various high-level tools using tabled                                            |
| [`util`](_autosummary/tabled.util.html.md#module-tabled.util)                     | General-purpose utilities for working with DataFrames, dicts, and byte decoding. |
| [`wrappers`](_autosummary/tabled.wrappers.html.md#module-tabled.wrappers)             | Wrapping tools                                                                   |


# _autosummary/tabled.join_tables.html.md

# tabled.join_tables

Join multiple tables (pandas DataFrames) down to a target subset of columns.

Given a mapping of tables and the set of columns you want in the result, this
module figures out which pairs of tables to join, in what order, and which
overlapping fields to drop at each step, so the final result has exactly the
target columns.

Main entry points:

- `Join`: a join operation paired with optional fields to remove.
- `minimum_covering_tree`: the minimal tree of table joins covering the target subset.
- `generate_join_sequence`: the ordered sequence of `Join` operations to run.
- `compute_join_resolution`: carries out a join sequence and returns the result.

### Example

```pycon
>>> tables = {
...     'A': pd.DataFrame({'b': [1, 2, 3, 33], 'c': [4, 5, 6, 66]}),
...     'B': pd.DataFrame(
...         {
...             'b': [1, 2, 3],
...             'a': [4, 5, 6],
...             'd': [7, 8, 9],
...             'e': [10, 11, 12],
...             'f': [13, 14, 15],
...         }
...     ),
...     'C': pd.DataFrame({'f': [13, 14, 15], 'g': [4, 5, 6]}),
...     'D': pd.DataFrame(
...         {'d': [7, 8, 77], 'e': [10, 11, 77], 'h': [7, 8, 9], 'i': [1, 2, 3]}
...     ),
...     'E': pd.DataFrame({'i': [1, 2, 3], 'j': [4, 5, 6]}),
... }
>>> target_sub_set = {'b', 'g', 'j'}
>>> leaf_edges = get_leaf_edges(tables, target_sub_set)
>>> leaf_edges
[('B', 'C'), ('D', 'E')]
>>> join_sequence = generate_join_sequence(tables, leaf_edges, target_sub_set)
>>> join_sequence
['B', Join('C', remove=['a', 'f']), Join('D', remove=['d', 'e', 'h']), Join('E', remove=['i'])]
>>> join_result = compute_join_resolution(join_sequence, tables)
>>> join_result
   b  g  j
0  1  4  4
1  2  5  5
```

### Functions

| [`compute_join_resolution`](_autosummary/tabled.join_tables.html.md#tabled.join_tables.compute_join_resolution)(resolution_sequence, ...)   | Carries `resolution_sequence` join operations out with tables taken from `tables`.                                                                         |
|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [`determine_remove_fields`](_autosummary/tabled.join_tables.html.md#tabled.join_tables.determine_remove_fields)(labeled_sets, ...)          | Determine which fields should be removed for a given table                                                                                                 |
| [`ensure_join_op`](_autosummary/tabled.join_tables.html.md#tabled.join_tables.ensure_join_op)(obj)                                 | Return `obj` if it is already a `Join`, else wrap it as `Join(obj)` (no fields removed).                                                                   |
| [`generate_join_sequence`](_autosummary/tabled.join_tables.html.md#tabled.join_tables.generate_join_sequence)(tables, leaf_edges, ...)     | Generate a sequence of joins with remove commands based on leaf edges                                                                                      |
| [`get_leaf_edges`](_autosummary/tabled.join_tables.html.md#tabled.join_tables.get_leaf_edges)(tables, target_subset[, ...])        | Return the covering-tree edges (see `minimum_covering_tree`) whose second table is a leaf (visited once).                                                  |
| [`minimum_covering_tree`](_autosummary/tabled.join_tables.html.md#tabled.join_tables.minimum_covering_tree)(tables, target_subset)        | Return the edges (pairs of table names) of a tree of joins covering `target_subset`.                                                                       |
| [`update_leaf_edges_after_removal`](_autosummary/tabled.join_tables.html.md#tabled.join_tables.update_leaf_edges_after_removal)(tables, ...)        | Update the list of leaf edges after removing an edge, ensuring that the resulting leaf edges do not lead to the loss of any elements in the target subset. |

### Classes

| [`Join`](_autosummary/tabled.join_tables.html.md#tabled.join_tables.Join)(table_id[, remove])   | A join step: which table to join in next, and which of its fields to drop after.   |
|-----------------------------------------------------------------------------|------------------------------------------------------------------------------------|

### *class* tabled.join_tables.Join(table_id, remove=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

A join step: which table to join in next, and which of its fields to drop after.

### tabled.join_tables.compute_join_resolution(resolution_sequence, tables)

Carries `resolution_sequence` join operations out with tables taken from `tables`.

* **Parameters:**
  * **resolution_sequence** ([`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)) – An iterable of join operations to carry out.
    Each join operation is either a table name (str) or a Join object.
    If it’s a Join object, it’s assumed that the table has already been joined
    and the fields to remove are in the `remove` attribute of the object.
  * **tables** ([`Mapping`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), `DataFrame`]) – A mapping of table names to tables (pd.DataFrame)
* **Return type:**
  `DataFrame`

### tabled.join_tables.determine_remove_fields(labeled_sets, target_sub_set, joined_tables, current_table)

Determine which fields should be removed for a given table

* **Parameters:**
  * **labeled_sets** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`set`](https://docs.python.org/3/builtins/stdtypes.html#set)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]) – The sets of elements labeled by nodes
  * **target_sub_set** ([`set`](https://docs.python.org/3/builtins/stdtypes.html#set)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – The target subset of elements that must remain covered
  * **joined_tables** ([`set`](https://docs.python.org/3/builtins/stdtypes.html#set)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – The set of tables that have been or will be joined
  * **current_table** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – The current table being processed
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]
* **Returns:**
  A list of fields to remove

### tabled.join_tables.ensure_join_op(obj)

Return `obj` if it is already a `Join`, else wrap it as `Join(obj)` (no fields removed).

### tabled.join_tables.generate_join_sequence(tables, leaf_edges, target_sub_set)

Generate a sequence of joins with remove commands based on leaf edges

* **Parameters:**
  * **leaf_edges** ([`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`tuple`](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]) – The list of leaf edges to process
  * **labeled_sets** – The sets of elements labeled by nodes
  * **target_sub_set** ([`set`](https://docs.python.org/3/builtins/stdtypes.html#set)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – The target subset of elements that must remain covered
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Join`](_autosummary/tabled.join_tables.html.md#tabled.join_tables.Join)]
* **Returns:**
  A list of Join operations

### tabled.join_tables.get_leaf_edges(tables, target_subset, start_node=None)

Return the covering-tree edges (see `minimum_covering_tree`) whose second table is a leaf (visited once).

* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`tuple`](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`KT`), [`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`KT`)]]

### tabled.join_tables.minimum_covering_tree(tables, target_subset, start_node=None)

Return the edges (pairs of table names) of a tree of joins covering `target_subset`.

Walks the tables’ column-overlap graph breadth-first from `start_node`
(or an arbitrary table if not given), accumulating edges until every
column in `target_subset` is covered by the tables seen so far.

### tabled.join_tables.update_leaf_edges_after_removal(tables, target_sub_set, current_leaf_edges)

Update the list of leaf edges after removing an edge, ensuring that the resulting
leaf edges do not lead to the loss of any elements in the target subset.

* **Parameters:**
  * **tables** ([`Mapping`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), `DataFrame`]) – A mapping of table names to tables (pd.DataFrame).
  * **target_sub_set** ([`set`](https://docs.python.org/3/builtins/stdtypes.html#set)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – The target subset of columns that must remain covered.
  * **current_leaf_edges** ([`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`tuple`](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]) – The current list of leaf edges.
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`tuple`](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]
* **Returns:**
  An updated list of leaf edges.


# _autosummary/tabled.misc.html.md

# tabled.misc

Miscellaneous utility functions for tables.


# _autosummary/tabled.multi.html.md

# tabled.multi

Multi-tabled data structures.

### Functions

| [`columns_of_all_tables`](_autosummary/tabled.multi.html.md#tabled.multi.columns_of_all_tables)(tables)                   | Return all columns from all tables, in order of first appearance.                            |
|--------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------|
| [`columns_of_first_table`](_autosummary/tabled.multi.html.md#tabled.multi.columns_of_first_table)(tables)                  | Return the column names of the first table in `tables`.                                      |
| [`dataframes`](_autosummary/tabled.multi.html.md#tabled.multi.dataframes)(tables)                              | Cast to an iterable of dataframes.                                                           |
| [`execute_commands`](_autosummary/tabled.multi.html.md#tabled.multi.execute_commands)(commands, scope, ...[, ...])   | Carries `commands` operations out with tables taken from `scope`.                            |
| [`execute_table_commands`](_autosummary/tabled.multi.html.md#tabled.multi.execute_table_commands)(commands, tables[, ...]) | Run `commands` (`Load`/`Join`/`Remove`/`Rename`) against `tables`; see `execute_commands`.   |
| [`join_func`](_autosummary/tabled.multi.html.md#tabled.multi.join_func)(scope, command)                       | Interpreter for `Join`: inner-merge the table at `command.table_key` into `scope["cumul"]`.  |
| [`load_func`](_autosummary/tabled.multi.html.md#tabled.multi.load_func)(scope, command)                       | Interpreter for `Load`: set `scope["cumul"]` to `scope[command.key]`.                        |
| [`mapping_of_dataframes`](_autosummary/tabled.multi.html.md#tabled.multi.mapping_of_dataframes)(tables)                   | Cast to a mapping of dataframes                                                              |
| [`remove_func`](_autosummary/tabled.multi.html.md#tabled.multi.remove_func)(scope, command)                     | Interpreter for `Remove`: drop `command.fields` from `scope["cumul"]`.                       |
| [`rename_func`](_autosummary/tabled.multi.html.md#tabled.multi.rename_func)(scope, command)                     | Interpreter for `Rename`: rename `scope["cumul"]` columns and record the mapping in `scope`. |
| [`set_scope_value`](_autosummary/tabled.multi.html.md#tabled.multi.set_scope_value)(scope, key, value)              | Set `scope[key] = value` (in place).                                                         |

### Classes

| [`ColumnOrientedMapping`](_autosummary/tabled.multi.html.md#tabled.multi.ColumnOrientedMapping)(tables[, columns])   | A `{column_name: concatenated_column_values}` view over several tables.          |
|---------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------|
| [`Join`](_autosummary/tabled.multi.html.md#tabled.multi.Join)(table_key)                            | Command: inner-join the accumulator with the table at `scope[table_key]`.        |
| [`Load`](_autosummary/tabled.multi.html.md#tabled.multi.Load)(key)                                  | Command: set the accumulator (`scope["cumul"]`) to `scope[key]`.                 |
| [`Remove`](_autosummary/tabled.multi.html.md#tabled.multi.Remove)(fields)                             | Command: drop `fields` (column or columns) from the accumulator.                 |
| [`Rename`](_autosummary/tabled.multi.html.md#tabled.multi.Rename)(rename_mapping)                     | Command: rename accumulator columns per `rename_mapping` (old name -> new name). |

### *class* tabled.multi.ColumnOrientedMapping(tables, columns=<function columns_of_first_table>)

Bases: [`Mapping`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping)

A `{column_name: concatenated_column_values}` view over several tables.

Keys are column names (by default, the columns of the first table);
each value is that column concatenated across all `tables`.

#### array(columns=None)

Concatenate a single column from all tables into one array.

`columns` must be a single column name (not a list): `.df(columns)`
then has to return a Series (not a DataFrame) for `.array` to work.

#### *property* columns

The columns that will be used in this mapping (the keys of the mapping)

#### columns_of_all_tables()

Return all columns from all tables, in order of first appearance.
This is useful for making a ColumnOrientedMapping without reverting to
the default columns argument, which is to use the columns of the first table.

* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`Column`)]

#### columns_of_first_table()

Return the column names of the first table in `tables`.

* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`Column`)]

#### df(columns=None)

Concatenate the given columns (all columns by default) from all tables into one dataframe.

### *class* tabled.multi.Join(table_key)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Command: inner-join the accumulator with the table at `scope[table_key]`.

### *class* tabled.multi.Load(key)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Command: set the accumulator (`scope["cumul"]`) to `scope[key]`.

### *class* tabled.multi.Remove(fields)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Command: drop `fields` (column or columns) from the accumulator.

### *class* tabled.multi.Rename(rename_mapping)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Command: rename accumulator columns per `rename_mapping` (old name -> new name).

### tabled.multi.columns_of_all_tables(tables)

Return all columns from all tables, in order of first appearance.
This is useful for making a ColumnOrientedMapping without reverting to
the default columns argument, which is to use the columns of the first table.

* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`Column`)]

### tabled.multi.columns_of_first_table(tables)

Return the column names of the first table in `tables`.

* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`Column`)]

### tabled.multi.dataframes(tables)

Cast to an iterable of dataframes.

* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[`DataFrame`]

### tabled.multi.execute_commands(commands, scope, interpreter_map, , extra_scope=None)

Carries `commands` operations out with tables taken from `scope`.

* **Parameters:**
  **commands** ([`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)) – An iterable of join operations to carry out.

### tabled.multi.execute_table_commands(commands, tables, interpreter_map={<class 'tabled.multi.Join'>: <function join_func>, <class 'tabled.multi.Load'>: <function load_func>, <class 'tabled.multi.Remove'>: <function remove_func>, <class 'tabled.multi.Rename'>: <function rename_func>}, \*, extra_scope=None)

Run `commands` (`Load`/`Join`/`Remove`/`Rename`) against `tables`; see `execute_commands`.

### tabled.multi.join_func(scope, command)

Interpreter for `Join`: inner-merge the table at `command.table_key` into `scope["cumul"]`.

If `scope["renamed_columns"]` was set by a prior `Rename`, that column
renaming is applied to the joined table first, so a later rename stays
consistent across joins.

### tabled.multi.load_func(scope, command)

Interpreter for `Load`: set `scope["cumul"]` to `scope[command.key]`.

### tabled.multi.mapping_of_dataframes(tables)

Cast to a mapping of dataframes

* **Return type:**
  [`Mapping`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping)[[`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`KT`), `DataFrame`]

### tabled.multi.remove_func(scope, command)

Interpreter for `Remove`: drop `command.fields` from `scope["cumul"]`.

### tabled.multi.rename_func(scope, command)

Interpreter for `Rename`: rename `scope["cumul"]` columns and record the mapping in `scope`.

### tabled.multi.set_scope_value(scope, key, value)

Set `scope[key] = value` (in place).


# _autosummary/tabled.sqlite_tools.html.md

# tabled.sqlite_tools

General-purpose SQLite to DataFrame/Parquet export tools using DuckDB.

This module provides utilities for extracting data from SQLite databases and exporting
it to pandas DataFrames or Parquet files. It uses DuckDB with the sqlite_scanner
extension for efficient data extraction.

Key functions:

- export_sqlite_to_dataframes: Extract SQLite tables to pandas DataFrames
- export_sqlite_to_parquet: Export SQLite tables directly to Parquet files
- export_sqlite_to_dataframes_and_parquet: Combined export to both formats

All functions use DuckDB’s sqlite_scanner extension which provides fast, efficient
access to SQLite databases without loading the entire database into memory.

### Functions

| [`export_sqlite_query_to_parquet`](_autosummary/tabled.sqlite_tools.html.md#tabled.sqlite_tools.export_sqlite_query_to_parquet)(...[, ...])      | Export an arbitrary SQL query (against the attached SQLite DB) to a Parquet file.   |
|--------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------|
| [`export_sqlite_to_dataframes`](_autosummary/tabled.sqlite_tools.html.md#tabled.sqlite_tools.export_sqlite_to_dataframes)(sqlite_db_file, \*) | Export tables from SQLite to pandas DataFrames using DuckDB + sqlite_scanner.       |
| [`export_sqlite_to_dataframes_and_parquet`](_autosummary/tabled.sqlite_tools.html.md#tabled.sqlite_tools.export_sqlite_to_dataframes_and_parquet)(...)    | Export SQLite tables to both DataFrames and Parquet files.                          |
| [`export_sqlite_to_parquet`](_autosummary/tabled.sqlite_tools.html.md#tabled.sqlite_tools.export_sqlite_to_parquet)(sqlite_db_file, ...)   | Export tables from a SQLite .db file to Parquet using DuckDB + sqlite_scanner.      |

### tabled.sqlite_tools.export_sqlite_query_to_parquet(sqlite_db_file, out_path, , query, schema='src', compression='ZSTD', install_extensions=True, verbose=False)

Export an arbitrary SQL query (against the attached SQLite DB) to a Parquet file.

Useful for generating:

- edge lists (source/target)
- node tables (id + attributes)
- filtered subsets

### Example

```python
export_sqlite_query_to_parquet(
    "my.db",
    "edges.parquet",
    query="SELECT from_id AS source, to_id AS target, weight FROM edges",
)
```

* **Return type:**
  [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)

### tabled.sqlite_tools.export_sqlite_to_dataframes(sqlite_db_file, , tables=None, schema='src', install_extensions=True, verbose=False)

Export tables from SQLite to pandas DataFrames using DuckDB + sqlite_scanner.

* **Parameters:**
  * **sqlite_db_file** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Path to the SQLite database file (.db / .sqlite / .sqlite3).
  * **tables** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`Sequence`](https://docs.python.org/3/library/typing.html#typing.Sequence)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]) – Optional list of table names to export. If None, exports all discovered tables.
  * **schema** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – DuckDB schema name to attach the SQLite DB as (default “src”).
  * **install_extensions** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, runs INSTALL/LOAD sqlite_scanner (helpful for first run).
  * **verbose** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Print progress.
* **Returns:**
  Dictionary mapping table names to DataFrames.
* **Return type:**
  [`Dict`](https://docs.python.org/3/library/typing.html#typing.Dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), `DataFrame`]

### tabled.sqlite_tools.export_sqlite_to_dataframes_and_parquet(sqlite_db_file, out_dir=None, , tables=None, schema='src', compression='ZSTD', overwrite=True, install_extensions=True, verbose=False)

Export SQLite tables to both DataFrames and Parquet files.

This is a combined function that exports SQLite tables to pandas DataFrames
and optionally saves them to Parquet files in a single operation.

* **Parameters:**
  * **sqlite_db_file** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Path to the SQLite database file (.db / .sqlite / .sqlite3).
  * **out_dir** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path), [`None`](https://docs.python.org/3/builtins/constants.html#None)]) – Optional directory where Parquet files will be written.
    If None, only DataFrames are returned.
  * **tables** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`Sequence`](https://docs.python.org/3/library/typing.html#typing.Sequence)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]) – Optional list of table names to export. If None, exports all tables.
  * **schema** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – DuckDB schema name to attach the SQLite DB as (default “src”).
  * **compression** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Parquet compression codec. Common: “ZSTD”, “SNAPPY”, “GZIP”, “NONE”.
  * **overwrite** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If False, skip exporting tables where parquet files already exist.
  * **install_extensions** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, runs INSTALL/LOAD sqlite_scanner (helpful for first run).
  * **verbose** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Print progress information.
* **Returns:**
  A tuple containing:
  - Dictionary mapping table names to DataFrames
  - Output directory path (if out_dir was provided)
* **Return type:**
  [`tuple`](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[`Dict`](https://docs.python.org/3/library/typing.html#typing.Dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), `DataFrame`], [`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]]

### tabled.sqlite_tools.export_sqlite_to_parquet(sqlite_db_file, out_dir, , tables=None, schema='src', compression='ZSTD', overwrite=True, install_extensions=True, verbose=False)

Export tables from a SQLite .db file to Parquet using DuckDB + sqlite_scanner.

This is a general-purpose exporter that:

- attaches the SQLite file to DuckDB
- discovers tables (or uses the provided list)
- writes each table to <out_dir>/<table>.parquet

* **Parameters:**
  * **sqlite_db_file** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Path to the SQLite database file (.db / .sqlite / .sqlite3).
  * **out_dir** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Directory where Parquet files will be written.
  * **tables** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`Sequence`](https://docs.python.org/3/library/typing.html#typing.Sequence)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]) – Optional list of table names to export. If None, exports all discovered tables.
  * **schema** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – DuckDB schema name to attach the SQLite DB as (default “src”).
  * **compression** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Parquet compression codec. Common: “ZSTD”, “SNAPPY”, “GZIP”, “NONE”.
  * **overwrite** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If False, skip exporting a table if the target parquet file already exists.
  * **install_extensions** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, runs INSTALL/LOAD sqlite_scanner (helpful for first run).
  * **verbose** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Print progress.
* **Returns:**
  The output directory (resolved).
* **Return type:**
  [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)


# _autosummary/tabled.tools.html.md

# tabled.tools

Various high-level tools using tabled

### Functions

| [`diagnose_table_collection`](_autosummary/tabled.tools.html.md#tabled.tools.diagnose_table_collection)(tables, \*[, ...])   | Diagnose a collection of tables and return diagnostic information.   |
|-------------------------------------------------------------------------------------------------|----------------------------------------------------------------------|

### tabled.tools.diagnose_table_collection(tables, \*, info_funcs={'categorical_stats': <function \_get_categorical_stats>, 'columns': <function \_get_columns>, 'first_row': <function \_get_first_row>, 'numeric_stats': <function \_get_numeric_stats>, 'sample_rows': <function \_get_sample_rows>, 'shape': <function \_get_shape>}, egress=<class 'dict'>)

Diagnose a collection of tables and return diagnostic information.

* **Parameters:**
  * **tables** – 

    Collection of tables - can be:
    - A mapping from keys to DataFrames
    - A non-mapping, non-string iterable of DataFrames (will use enumerate for keys)
    - A string URI to create DfFiles mapping
  * **info_funcs** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Callable`](https://docs.python.org/3/library/typing.html#typing.Callable)]) – Dictionary of info functions to apply
  * **egress** ([`Callable`](https://docs.python.org/3/library/typing.html#typing.Callable)) – Function to process the generator of (table_key, info_dict) pairs
* **Returns:**
  Result of egress applied to the info generator
* **Raises:**
  [**TypeError**](https://docs.python.org/3/builtins/exceptions.html#TypeError) – If `tables` is not a mapping, iterable, or string URI.

### Examples

```pycon
>>> import pandas as pd
```

### Mapping case

```pycon
>>> tables_dict = {'table1': pd.DataFrame({'a': [1, 2], 'b': [3, 4]})}
>>> result = diagnose_table_collection(tables_dict)
>>> 'table1' in result
True
```

### Iterable case

```pycon
>>> df1 = pd.DataFrame({'a': [1, 2]})
>>> df2 = pd.DataFrame({'b': [3, 4]})
>>> result = diagnose_table_collection([df1, df2])
>>> 0 in result and 1 in result
True
```


# _autosummary/tabled.util.html.md

# tabled.util

General-purpose utilities for working with DataFrames, dicts, and byte decoding.

### Functions

| [`auto_decode_bytes`](_autosummary/tabled.util.html.md#tabled.util.auto_decode_bytes)(b, \*[, try_first_bytes, ...])   | Decode a byte sequence into a string, trying charset_normalizer gueses if fails.                                                                             |
|-----------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [`breadth_first_traversal`](_autosummary/tabled.util.html.md#tabled.util.breadth_first_traversal)(graph, start_node, \*)     | Yields nodes starting from the root node, expanding to neighbors recursively, using breadth-first search, without repeating nodes.                           |
| [`collapse_columns`](_autosummary/tabled.util.html.md#tabled.util.collapse_columns)(df, groupings)                    | Transforms specified columns of a dataframe into single columns where each row contains a dictionary of column names and values from the original dataframe. |
| [`collapse_rows`](_autosummary/tabled.util.html.md#tabled.util.collapse_rows)(df, by, \*[, container])             | Do a groupby to collapse (the rows of) a dataframe, gathering the other column's values (the ones that are not keys of the groupby) into lists.              |
| [`column_sep_key_mapper`](_autosummary/tabled.util.html.md#tabled.util.column_sep_key_mapper)(key, column_name, sep)       | Join `column_name` and `key` with `sep` (e.g. `"X"`, `"a"`, `"."` -> `"X.a"`).                                                                               |
| [`duplicate_groups`](_autosummary/tabled.util.html.md#tabled.util.duplicate_groups)(df, subset, \*[, output, ...])    | Get a DataFrame containing rows that have duplicate values for subset of columns.                                                                            |
| [`ensure_columns`](_autosummary/tabled.util.html.md#tabled.util.ensure_columns)(df[, columns, fill])                | Ensure that a dataframe has certain columns, filling them with a certain value if they don't exist.                                                          |
| [`ensure_first_columns`](_autosummary/tabled.util.html.md#tabled.util.ensure_first_columns)(df[, columns])                | Ensure that the given columns come first (if they exist), with the rest of the columns following in the order they were in the original dataframe.           |
| [`ensure_last_columns`](_autosummary/tabled.util.html.md#tabled.util.ensure_last_columns)(df[, columns])                 | Ensure that the given columns come last (if they exist), with the rest of the columns preceding in the order they were in the original dataframe.            |
| [`expand_columns`](_autosummary/tabled.util.html.md#tabled.util.expand_columns)(df, expand_columns, \*[, ...])      | Expands the iterable values of specified columns in to new columns.                                                                                          |
| [`expand_rows`](_autosummary/tabled.util.html.md#tabled.util.expand_rows)(df, grouped_columns)                   | Expands a DataFrame where specific columns were collapsed into containers back to its original form.                                                         |
| [`identity`](_autosummary/tabled.util.html.md#tabled.util.identity)(x)                                        | Return `x` unchanged.                                                                                                                                        |
| [`intersection_graph`](_autosummary/tabled.util.html.md#tabled.util.intersection_graph)(sets[, edge_labels])            | A graph of all intersections between sets.                                                                                                                   |
| [`invert_labeled_collection`](_autosummary/tabled.util.html.md#tabled.util.invert_labeled_collection)(d[, values_container])   | Invert a mapping whose values are iterables of objects, getting a mapping from objects to iterables of keys.                                                 |
| [`is_instance_of`](_autosummary/tabled.util.html.md#tabled.util.is_instance_of)(class_or_tuple)                     | Return a predicate `obj -> isinstance(obj, class_or_tuple)`.                                                                                                 |
| [`is_non_null_or_empty`](_autosummary/tabled.util.html.md#tabled.util.is_non_null_or_empty)(value)                        | Check if a value is not None, not empty, and not an empty list.                                                                                              |
| [`map_values`](_autosummary/tabled.util.html.md#tabled.util.map_values)(func, d)                                | Apply a function to all values of a dictionary.                                                                                                              |
| [`split_keys`](_autosummary/tabled.util.html.md#tabled.util.split_keys)(d)                                      | Returns a dictionary where keys that had spaces were split into multiple keys                                                                                |
| [`upsert_data`](_autosummary/tabled.util.html.md#tabled.util.upsert_data)(target_df, source_df[, axis, ...])     | Updates or Inserts (Upserts) data into a target DataFrame, handling initial creation and growth along a specified axis.                                      |

### Classes

| [`PandasJSONEncoder`](_autosummary/tabled.util.html.md#tabled.util.PandasJSONEncoder)(\*[, skipkeys, ...])   | A custom JSON encoder that can handle pandas and numpy types more robustly, even if they appear within nested data structures.   |
|-------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------|

### *class* tabled.util.PandasJSONEncoder(, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)

Bases: [`JSONEncoder`](https://docs.python.org/3/library/json.html#json.JSONEncoder)

A custom JSON encoder that can handle pandas and numpy types more robustly,
even if they appear within nested data structures.

```pycon
>>> import json, datetime, pandas as pd, numpy as np
>>> # Test with a DataFrame containing timestamps and missing values.
>>> df = pd.DataFrame({
...     'a': [1, 2, 3],
...     'b': [pd.Timestamp('2023-04-09 00:02:53+0000', tz='UTC'),
...           pd.NaT,
...           pd.Timestamp('2023-04-09 00:02:53+0000', tz='UTC')]
... })
>>> json_str = json.dumps(df, cls=PandasJSONEncoder)
>>> json_str
'[{"a": 1, "b": "2023-04-09T00:02:53..."}..., {"a": 2, "b": null}, {"a": 3, "b": "2023-04-09T00:02:53..."}...]'
```

```pycon
>>> # Test with a Series containing timestamps and missing values.
>>> s = pd.Series([pd.Timestamp('2023-04-09 00:02:53+0000', tz='UTC'), pd.NaT])
>>> json_str = json.dumps(s, cls=PandasJSONEncoder)
>>> json_str
'{"0": "2023-04-09T00:02:53...", "1": null}'
```

```pycon
>>> # Test with numpy arrays and numpy scalar types.
>>> data = {
...     "arr": np.array([1, 2, 3], dtype=np.int32),
...     "flt": np.float32(3.14),
...     "bool": np.bool_(False)
... }
>>> json_str = json.dumps(data, cls=PandasJSONEncoder)
>>> json_str
'{"arr": [1, 2, 3], "flt": 3.14..., "bool": false}'
```

```pycon
>>> # Test with a datetime.date.
>>> date_val = datetime.date(2002, 1, 1)
>>> json.dumps(date_val, cls=PandasJSONEncoder)
'"2002-01-01"'
```

#### default(obj)

Convert `obj` (a pandas/numpy value the default encoder can’t handle) to a JSON-safe value.

### tabled.util.auto_decode_bytes(b, , try_first_bytes=(1000000.0, 10000000.0, 100000000.0), encoding='utf-8', verbose=False)

Decode a byte sequence into a string, trying charset_normalizer gueses if fails.

This function attempts to decode the given bytes using the default encoding (usually ‘utf-8’).
If that fails due to a `UnicodeDecodeError`, it uses `charset_normalizer` to detect the encoding
by analyzing increasingly larger samples of the byte sequence, as specified in `try_first_bytes`.
If all attempts fail, it analyzes the entire byte sequence to detect the encoding.

* **Parameters:**
  * **b** ([`bytes`](https://docs.python.org/3/builtins/stdtypes.html#bytes)) – The byte sequence to decode.
  * **try_first_bytes** – Byte lengths to use for encoding detection samples.
  * **encoding** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – The encoding to try first, before falling back to detection.
  * **verbose** – If True, print each encoding tried.
* **Return type:**
  [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)
* **Returns:**
  The decoded string.
* **Raises:**
  [**UnicodeDecodeError**](https://docs.python.org/3/builtins/exceptions.html#UnicodeDecodeError) – If the byte sequence cannot be decoded after all attempts.

### Examples

```pycon
>>> # Example with UTF-8 encoded bytes
>>> s = 'Hello, world! Привет мир! こんにちは世界！'
>>> b_utf8 = s.encode('utf-8')
>>> auto_decode_bytes(b_utf8) == s
True
```

```pycon
>>> # Example with UTF-16 encoded bytes
>>> s_utf16 = 'Hello, world! 你好，世界！'
>>> b_utf16 = s_utf16.encode('utf-16')
>>> auto_decode_bytes(b_utf16) == s_utf16
True
```

Now, this is auto_decoding, but it doesn’t mean it’s robust.
We use `charset_normalizer` to detect the encoding of the bytes, and then
try to decode it with that encoding.
But sometimes you can decode something that is not the original string,
so be careful!!
It’s annoying to have to specify the encoding all the time, but this
explicitness, and the errors that come with it, can be vital.

Here are a few examples. We’ll

```pycon
>>> s_latin1 = 'Héllo, wörld! Ça va?'
>>> b_latin1 = s_latin1.encode('latin-1')  # latin-1 is ISO-8859-1
>>> decoded_s = auto_decode_bytes(b_latin1, verbose=True)
Trying encoding: 'utf-8'
Trying encoding: ...
>>> decoded_s
'H幨lo, w顤ld! ド va?'
>>> decoded_s == s_latin1
False
```

(Note in the above that some tests were skipped. This is because the output
is not deterministic and can vary depending on the system and the version of
`charset_normalizer`.)

```pycon
>>> s_cp1252 = 'Special characters: € £ ¥ © ®'
>>> b_cp1252 = s_cp1252.encode('cp1252')  # i.e. 'Windows-1252'
>>> decoded_s = auto_decode_bytes(b_cp1252, verbose=True)
Trying encoding: 'utf-8'
Trying encoding: 'cp1125'
>>> # See that charset_normalizer
>>> decoded_s
'Special characters: А г е й о'
```

### tabled.util.breadth_first_traversal(graph, start_node, , yield_edges=False)

Yields nodes starting from the root node, expanding to neighbors recursively,
using breadth-first search, without repeating nodes.

* **Parameters:**
  * **graph** ([`Mapping`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping)) – Adjacencies of the graph: A mapping from nodes to their neighbors.
  * **start_node** – The node to start from (key of the graph adjacency mapping)
  * **yield_edges** – If True, yield edges instead of nodes.
    The edges are yielded as tuples of (node, neighbor).

```pycon
>>> graph = {
...     'A': ['B'], 'B': ['A', 'C', 'D'], 'C': ['B'], 'D': ['B', 'E'], 'E': ['D']
... }
>>> list(breadth_first_traversal(graph, 'B'))
['B', 'A', 'C', 'D', 'E']
>>> list(breadth_first_traversal(graph, 'B', yield_edges=True))
[('B', 'A'), ('B', 'C'), ('B', 'D'), ('D', 'E')]
```

### tabled.util.collapse_columns(df, groupings)

Transforms specified columns of a dataframe into single columns where each row
contains a dictionary of column names and values from the original dataframe.

* **Parameters:**
  * **df** (`DataFrame`) – The dataframe to transform.
  * **groupings** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]] | [`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`KT`)]) – A mapping that indicates which columns to collapse into dictionaries
    and what to call the new resulting column.
    If only a list of column names to be collapsed is given, it will be interpreted as
    the group_column_names in a single `{"collapsed": group_column_names}` dictionary,
    that is, all `group_column_names` are to be collapsed in to a single collapsed column.
* **Return type:**
  `DataFrame`
* **Returns:**
  A dataframe with the original columns not specified in `columns` untouched,
  and a new column `new_column_name` containing dictionaries of the collapsed columns.
* **Raises:**
  [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If none of a grouping’s column names are found in `df`.

### Example

```pycon
>>> df = pd.DataFrame({
...     'a': [1, 1, 2, 2],
...     'b': [3, 4, 5, 6],
...     'c': [7, 8, 9, 10]
... })
>>> df
   a  b   c
0  1  3   7
1  1  4   8
2  2  5   9
3  2  6  10
>>> collapse_columns(df, {'ab': ['a', 'b']})
   c   ab
0  7  {'a': 1, 'b': 3}
1  8  {'a': 1, 'b': 4}
2  9  {'a': 2, 'b': 5}
3 10  {'a': 2, 'b': 6}
```

### tabled.util.collapse_rows(df, by, \*, container=<class 'list'>)

Do a groupby to collapse (the rows of) a dataframe, gathering the other
column’s values (the ones that are not keys of the groupby) into lists.

* **Parameters:**
  * **df** (`DataFrame`) – the dataframe to collapse
  * **by** ([`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`KT`)]) – the columns to group by (the keys of the groupby)
  * **container** ([`Callable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)[[[`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)], [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)]) – the container to use to gather the other columns values
* **Return type:**
  `DataFrame`

```pycon
>>> df = pd.DataFrame({
...     'a': [1, 1, 2, 2],
...     'b': [3, 4, 5, 6],
...     'c': [7, 8, 9, 10]
... })
>>> df
   a  b   c
0  1  3   7
1  1  4   8
2  2  5   9
3  2  6  10
>>> collapse_rows(df, ['a'])
   a       b        c
0  1  [3, 4]   [7, 8]
1  2  [5, 6]  [9, 10]
```

### tabled.util.column_sep_key_mapper(key, column_name, sep)

Join `column_name` and `key` with `sep` (e.g. `"X"`, `"a"`, `"."` -> `"X.a"`).

### tabled.util.duplicate_groups(df, subset, , output='dataframe', keep_indices=True)

Get a DataFrame containing rows that have duplicate values for subset of columns.

* **Parameters:**
  * **df** – Input DataFrame
  * **subset** – Column name or list of column names to identify duplicates
  * **output** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Output format, either “dataframe” or “series”
  * **keep_indices** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True (default), preserves the original index as a column named
    by the index name or ‘index’ if unnamed. If False, keeps the
    original index as the index of the result.
* **Returns:**
  Series with unique duplicate values as index and corresponding DataFrames as values
  or DataFrame with duplicated rows with the specified subset as index.
* **Raises:**
  [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If `output` is not `"dataframe"` or `"series"`.

```pycon
>>> import pandas as pd
>>> df = pd.DataFrame({"A": [1, 1, 2, 3, 3], "B": ["a", "b", "c", "d", "e"]})
>>> dups = duplicate_groups(df, "A")
>>> dups
   B  index
A
1  a      0
1  b      1
3  d      3
3  e      4
>>> list(dups.index)
[1, 1, 3, 3]
>>> dups.loc[1].shape
(2, 2)
>>> dups = duplicate_groups(df, "A", output="series")
>>> list(dups.index)
[1, 3]
>>> dups[1].shape
(2, 2)
>>> # Without keep_indices
>>> dups_orig_idx = duplicate_groups(df, "A", keep_indices=False)
>>> dups_orig_idx
   B
A
1  a
1  b
3  d
3  e
```

### tabled.util.ensure_columns(df, columns=(), fill=None)

Ensure that a dataframe has certain columns, filling them with a certain value
if they don’t exist.

### tabled.util.ensure_first_columns(df, columns=())

Ensure that the given columns come first (if they exist), with the rest of the columns
following in the order they were in the original dataframe.

### tabled.util.ensure_last_columns(df, columns=())

Ensure that the given columns come last (if they exist), with the rest of the columns
preceding in the order they were in the original dataframe.

### tabled.util.expand_columns(df, expand_columns, \*, drop=True, key_mapper=functools.partial(<function column_sep_key_mapper>, sep='.'), drop_non_iterable_rows=False)

Expands the iterable values of specified columns in to new columns.
The new columns will be named using the column_name and the key of the values of
the iterable that is expanded (key if dict, integer index if sequence).

* **Parameters:**
  * **df** (`DataFrame`) – The dataframe to transform.
  * **expand_columns** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – A list of column names whose values are dictionaries
    that need to be expanded into new columns.
  * **drop** – Whether to drop the original columns that were expanded.
  * **drop_non_iterable_rows** – Whether to drop rows that have non-iterable values
  * **key_mapper** – A function that takes a key and a column name and returns a
    new key. By default, the new key is the concatenation of the column name and
    the original key. If None, will just take the original key. The reason for
    also taking the column_name by default is to avoid collisions if the keys are
    used in more than one column.
* **Return type:**
  `DataFrame`
* **Returns:**
  A dataframe with the expanded columns added.
* **Raises:**
  [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If a name in `expand_columns` is not a column of `df`.

### Examples

```pycon
>>> df = pd.DataFrame({
...     'c': [7, 8, 9, 10],
...     'X': [{'a': 1, 'b': 3}, {'a': 1, 'b': 4}, {'a': 2, 'b': 5}, {'a': 2, 'b': 6}]
... })
>>> expand_columns(df, ['X'])
   c  X.a  X.b
0  7  1  3
1  8  1  4
2  9  2  5
3 10  2  6
```

Let’s see what happens when the elements of an expanded column are lists instead of
dicts, we ask to not drop, and we use `key_mapper=None`:

```pycon
>>> df = pd.DataFrame({
...     'c': [7, 8, 9, 10],
...     'X': [[1, 3], [1, 4], [2, 5], [2, 6]]
... })
>>> expand_columns(df, ['X'], drop=False, key_mapper=None)
    c       X  0  1
0   7  [1, 3]  1  3
1   8  [1, 4]  1  4
2   9  [2, 5]  2  5
3  10  [2, 6]  2  6
```

### tabled.util.expand_rows(df, grouped_columns)

Expands a DataFrame where specific columns were collapsed into containers back to its original form.
Each column in `grouped_columns` should contain lists of the same length within each row.

* **Parameters:**
  * **df** (`DataFrame`) – The DataFrame to expand.
  * **grouped_columns** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`KT`)]) – The list of columns to expand
* **Return type:**
  `DataFrame`
* **Returns:**
  The expanded DataFrame.

```pycon
>>> df_collapsed = pd.DataFrame({
...     'a': [1, 2],
...     'b': [[3, 4], [5, 6, 66]],
...     'c': [[7, 8], [9, 10, 11]]
... })
>>> expand_rows(df_collapsed, ['b', 'c'])
    a  b   c
0  1  3   7
1  1  4   8
2  2  5   9
3  2  6  10
4  2  66  11
```

### tabled.util.identity(x)

Return `x` unchanged.

### tabled.util.intersection_graph(sets, edge_labels=False)

A graph of all intersections between sets.
(See [https://en.wikipedia.org/wiki/Intersection_graph](https://en.wikipedia.org/wiki/Intersection_graph).)

In graph theory, an adjacency list is a collection of sets used to represent a
finite graph.
Here, the vertices are the values of sets,
and there is an edge between two vertices if the sets intersect.
The weight of the edge is the size of the intersection.

* **Parameters:**
  * **sets** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`KT`), [`set`](https://docs.python.org/3/builtins/stdtypes.html#set)]) – A mapping of keys to sets of elements. These sets of elements will
    be the vertices of the graph.
  * **edge_labels** ([`Literal`](https://docs.python.org/3/library/typing.html#typing.Literal)[`'elements'`, `'size'`, `False`]) – If ‘elements’, the edge labels are the elements of the intersection.
    If ‘size’, the edge labels are the size of the intersection.
    If False, there are no edge labels.
* **Returns:**
  A graph, represented by an “adjacency list”
  (see [https://en.wikipedia.org/wiki/Adjacency_list](https://en.wikipedia.org/wiki/Adjacency_list))
  (a dict whose keys are the keys of the input `sets` dict, and whose values
  tell us what sets of `sets` intersect with it),
  optionally with some information about this intersection.

```pycon
>>> sets = {
...     'A': {'b', 'c'},
...     'B': {'a', 'b', 'd', 'e', 'f'},
...     'C': {'f', 'g'},
...     'D': {'d', 'e', 'h', 'i'},
...     'E': {'i', 'j'}
... }
>>> assert intersection_graph(sets) == {
...     'A': {'B'}, 'B': {'A', 'C', 'D'}, 'C': {'B'}, 'D': {'B', 'E'}, 'E': {'D'}
... }
>>> assert intersection_graph(sets, edge_labels='elements') == {
...     'A': {'B': {'b'}},
...     'B': {'A': {'b'}, 'C': {'f'}, 'D': {'d', 'e'}},
...     'C': {'B': {'f'}},
...     'D': {'B': {'d', 'e'}, 'E': {'i'}},
...     'E': {'D': {'i'}}
... }
>>> assert intersection_graph(sets, edge_labels='size') == {
...     'A': {'B': 1},
...     'B': {'A': 1, 'C': 1, 'D': 2},
...     'C': {'B': 1},
...     'D': {'B': 2, 'E': 1},
...     'E': {'D': 1}
... }
```

### tabled.util.invert_labeled_collection(d, values_container=<class 'list'>)

Invert a mapping whose values are iterables of objects,
getting a mapping from objects to iterables of keys.

* **Return type:**
  [`Mapping`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping)[[`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`VT`), [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`KT`)]]

```pycon
>>> original_dict = {
...     "X": ['a', 'b'],
...     "Y": ['a'],
...     "Z": ['a', 'b', 'c']
... }
>>> inverted_dict = invert_labeled_collection(original_dict)
>>> inverted_dict
{'a': ['X', 'Y', 'Z'], 'b': ['X', 'Z'], 'c': ['Z']}
>>> invert_labeled_collection(inverted_dict)
{'X': ['a', 'b'], 'Y': ['a'], 'Z': ['a', 'b', 'c']}
```

The `values_container` argument can be used to cast the values of the inverted dict.

```pycon
>>> assert (
...     invert_labeled_collection(original_dict, values_container=set)
...     == {'a': {'X', 'Y', 'Z'}, 'b': {'X', 'Z'}, 'c': {'Z'}}
... )
>>>
>>> d = {'a': 'apple', 'b': 'banana'}
>>> t = invert_labeled_collection(d, values_container=''.join)
>>> t
{'a': 'abbb', 'p': 'aa', 'l': 'a', 'e': 'a', 'b': 'b', 'n': 'bb'}
>>> invert_labeled_collection(t, ''.join)
{'a': 'apple', 'b': 'aaabnn'}
```

### tabled.util.is_instance_of(class_or_tuple)

Return a predicate `obj -> isinstance(obj, class_or_tuple)`.

### tabled.util.is_non_null_or_empty(value)

Check if a value is not None, not empty, and not an empty list.

Often used with pandas dataframes to check if a cell is null or non-empty.

```text
num_of_non_empties_in_row = df.map(is_non_null_or_empty).sum(axis=1)
num_of_non_empties_in_col = df.map(is_non_null_or_empty).sum(axis=0)
```

And then you can do:

```text
num_of_non_empties_in_row.sort_values(ascending=False) to see which rows have the least empties (most actual data)
```

### tabled.util.map_values(func, d)

Apply a function to all values of a dictionary.

```pycon
>>> map_values(lambda x: x ** 2, {1: 2, 3: 4})
{1: 4, 3: 16}
```

### tabled.util.split_keys(d)

Returns a dictionary where keys that had spaces were split into multiple keys

Meant to be a convenience function for the user to use when they want to define a
mapping where several keys map to the same value.

```pycon
>>> split_keys({'apple': 1, 'banana carrot': 2})
{'apple': 1, 'banana': 2, 'carrot': 2}
```

### tabled.util.upsert_data(target_df, source_df, axis=1, align_index_value=False)

Updates or Inserts (Upserts) data into a target DataFrame, handling initial
creation and growth along a specified axis.

The function returns a new DataFrame, even though it modifies the target
in-place for column updates (axis=1).

* **Parameters:**
  * **target_df** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[`DataFrame`]) – The DataFrame to be updated (can be None or empty).
  * **source_df** (`DataFrame`) – The DataFrame containing the new/source data.
  * **axis** ([`Literal`](https://docs.python.org/3/library/typing.html#typing.Literal)[`0`, `1`]) – 1 for adding columns (default), 0 for adding rows.
  * **align_index_value** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, the concatenation requires indices (or columns
    when axis=0) to match both in number AND value.
    If False, alignment is ignored (positional concat).
* **Return type:**
  `DataFrame`
* **Returns:**
  The updated DataFrame.
* **Raises:**
  [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If `align_index_value` is `False` and the row count (axis=1)
      or column count (axis=0) of `target_df` and `source_df` don’t match.

### Examples

```pycon
>>> # 1. Initial creation (target_df is None)
>>> df_target = None
>>> df_source_A = pd.DataFrame({'a': [1, 2], 'b': [3, 4]})
>>> df_target = upsert_data(df_target, df_source_A)
>>> df_target.equals(df_source_A)
True
```

```pycon
>>> # 2. Adding new columns (axis=1, default)
>>> df_source_B = pd.DataFrame({'c': [5, 6], 'd': [7, 8]})
>>> df_target = upsert_data(df_target, df_source_B)
>>> df_target.columns.tolist()
['a', 'b', 'c', 'd']
```

```pycon
>>> # 3. Overwriting existing columns (axis=1)
>>> # Indices must align when updating
>>> df_source_C = pd.DataFrame({'a': [10, 20], 'e': [30, 40]})
>>> df_target = upsert_data(df_target, df_source_C)
>>> df_target['a'].tolist()
[10, 20]
>>> df_target.columns.tolist()
['a', 'b', 'c', 'd', 'e']
```

```pycon
>>> # 4. Adding rows (axis=0)
>>> df_target_row = pd.DataFrame({'col1': [1], 'col2': [2]})
>>> df_source_row = pd.DataFrame({'col1': [3], 'col2': [4]})
>>> df_target_row = upsert_data(df_target_row, df_source_row, axis=0)
>>> df_target_row.shape
(2, 2)
>>> df_target_row['col1'].tolist()
[1, 3]
```


# _autosummary/tabled.wrappers.html.md

# tabled.wrappers

Wrapping tools

A lot of what is defined here are functions that are used to transform data.
More precisely, encode and decode data depending on it’s format, file extension, etc.

### Functions

| [`add_extension_codec`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.add_extension_codec)([extension, encoder, ...])      | Add an extension-based encoder and decoder to the extension-code mapping.                  |
|------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------|
| [`cast_to_parquet`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.cast_to_parquet)(data, \*args[, \_\_name_of_column]) | Convert data to DataFrame if necessary, then save as parquet.                              |
| [`default_io_resolver`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.default_io_resolver)(src)                            | Resolve `src` (a local path, an http(s)/graze URL, or bytes) to a binary file-like object. |
| [`df_from_data_according_to_key`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.df_from_data_according_to_key)(data, mapping, ...)   | Get a dataframe from a (data, mapping, key) triple                                         |
| [`df_from_data_given_ext`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.df_from_data_given_ext)(data, ext[, ext_mapping])    | Get a dataframe from a (data, ext) pair                                                    |
| [`extension_based_decoding`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.extension_based_decoding)(k, v, \*[, ...])           | Decode a value based on the extension of the key.                                          |
| [`extension_based_encoding`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.extension_based_encoding)(k, v, \*[, ...])           | Encode a value based on the extension of the key.                                          |
| [`extension_based_wrap`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.extension_based_wrap)([store, ...])                  | Add extension-based encoding and decoding to a store.                                      |
| [`file_extension`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.file_extension)(key)                                 | Get the file extension from a key                                                          |
| [`get_codec_mappings`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.get_codec_mappings)(\*[, ...])                       | Return `{"encoders": extension_to_encoder, "decoders": extension_to_decoder}`.             |
| [`get_extension`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.get_extension)(key)                                  | Return the extension of a file path.                                                       |
| [`get_file_ext`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.get_file_ext)(key)                                   | Get the file extension from a key                                                          |
| [`get_protocol`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.get_protocol)(url)                                   | Get the protocol of a url                                                                  |
| [`if_extension_not_present_add_it`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.if_extension_not_present_add_it)(filepath, ...)      | Append `extension` to `filepath` unless it's already there.                                |
| [`if_extension_present_remove_it`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.if_extension_present_remove_it)(filepath, ...)       | Strip a trailing `extension` from `filepath`, if present.                                  |
| [`key_func_mapping`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.key_func_mapping)(obj, mapping[, key, ...])          | Map an object to a value based on a key function                                           |
| [`map_values`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.map_values)(func, d, \*[, except_condition, ...])    | Map values of a dictionary, except for those that satisfy a condition.                     |
| [`print_current_mappings`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.print_current_mappings)()                            | Print the current extension-to-encoder and extension-to-decoder mappings.                  |
| [`resolve_to_dataframe`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.resolve_to_dataframe)(data, ext[, ext_mapping])      | Get a dataframe from a (data, ext) pair                                                    |
| [`save_df_to_zipped_tsv`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.save_df_to_zipped_tsv)(df, name[, sep, index])       | Save a dataframe to a zipped tsv file.                                                     |
| [`single_column_parquet_decode`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.single_column_parquet_decode)(b[, col])              | Decode a single-column parquet file into a list of sequences.                              |
| [`single_column_parquet_encode`](_autosummary/tabled.wrappers.html.md#tabled.wrappers.single_column_parquet_encode)(sequences[, col])      | Encode a list of sequences into a single-column parquet file.                              |

### tabled.wrappers.add_extension_codec(extension=None, , encoder=None, decoder=None, overwrite=False)

Add an extension-based encoder and decoder to the extension-code mapping.

Sure, you could just edit the underlying dictionaries directly, but the design gods
would not be pleased.

If no arguments are passed, it will print the current mappings.

* **Parameters:**
  * **extension** – The file extension to add the codec for. If None, it will print the current mappings.
  * **encoder** – The encoder function to add. If None, it will print the current mappings.
  * **decoder** – The decoder function to add. If None, it will print the current mappings.
  * **overwrite** – If True, it will overwrite the existing encoder/decoder for the given extension.
    If False, it will raise a ValueError if the extension already exists.
* **Returns:**
  None. It just adds to the in-memory mappings (or prints them).

### tabled.wrappers.cast_to_parquet(data, \*args, \_\_name_of_column='_\_single_column_values', \*\*kwargs)

Convert data to DataFrame if necessary, then save as parquet.

Handles:

- pandas.DataFrame: use as-is
- pandas.Series: convert to DataFrame using to_frame()
- list/other iterables: convert to Series then DataFrame

### tabled.wrappers.default_io_resolver(src)

Resolve `src` (a local path, an http(s)/graze URL, or bytes) to a binary file-like object.

* **Return type:**
  [`BinaryIO`](https://docs.python.org/3/library/typing.html#typing.BinaryIO)

### tabled.wrappers.df_from_data_according_to_key(data, mapping, key, \*\*extra_decoder_kwargs)

Get a dataframe from a (data, mapping, key) triple

### tabled.wrappers.df_from_data_given_ext(data, ext, ext_mapping={'arrow': functools.partial(<function read_from_bytes>, <function arrow_bytes_to_dataframe>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'csv': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'dta': functools.partial(<function read_from_bytes>, functools.partial(<function read_stata>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'feather': functools.partial(<function read_from_bytes>, <function read_feather>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'h5': functools.partial(<function read_from_bytes>, <function read_hdf>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'hdf5': functools.partial(<function read_from_bytes>, <function read_hdf>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'html': functools.partial(<function read_from_bytes>, functools.partial(<function read_html>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'json': functools.partial(<function read_from_bytes>, functools.partial(<function read_json>, orient='records'), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'orc': functools.partial(<function read_from_bytes>, <function read_orc>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'p': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'parquet': functools.partial(<function read_from_bytes>, <function read_parquet>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'pickle': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'pkl': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sas': functools.partial(<function read_from_bytes>, <function read_sas>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sav': functools.partial(<function read_from_bytes>, <function read_spss>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sql': functools.partial(<function read_from_bytes>, <function read_sql>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sqlite': functools.partial(<function read_from_bytes>, <function read_sql>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'stata': functools.partial(<function read_from_bytes>, functools.partial(<function read_stata>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'tsv': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, sep='\\\\t', index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'txt': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xls': functools.partial(<function read_from_bytes>, functools.partial(<function read_excel>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xlsx': functools.partial(<function read_from_bytes>, functools.partial(<function read_excel>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xml': functools.partial(<function read_from_bytes>, <function read_xml>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>)}, \*\*extra_decoder_kwargs)

Get a dataframe from a (data, ext) pair

* **Return type:**
  `DataFrame`

### tabled.wrappers.extension_based_decoding(k, v, \*, extension_to_decoder={'arrow': functools.partial(<function read_from_bytes>, <function arrow_bytes_to_dataframe>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'csv': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'dta': functools.partial(<function read_from_bytes>, functools.partial(<function read_stata>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'feather': functools.partial(<function read_from_bytes>, <function read_feather>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'h5': functools.partial(<function read_from_bytes>, <function read_hdf>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'hdf5': functools.partial(<function read_from_bytes>, <function read_hdf>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'html': functools.partial(<function read_from_bytes>, functools.partial(<function read_html>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'json': functools.partial(<function read_from_bytes>, functools.partial(<function read_json>, orient='records'), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'orc': functools.partial(<function read_from_bytes>, <function read_orc>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'p': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'parquet': functools.partial(<function read_from_bytes>, <function read_parquet>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'pickle': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'pkl': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sas': functools.partial(<function read_from_bytes>, <function read_sas>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sav': functools.partial(<function read_from_bytes>, <function read_spss>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sql': functools.partial(<function read_from_bytes>, <function read_sql>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sqlite': functools.partial(<function read_from_bytes>, <function read_sql>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'stata': functools.partial(<function read_from_bytes>, functools.partial(<function read_stata>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'tsv': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, sep='\\t', index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'txt': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xls': functools.partial(<function read_from_bytes>, functools.partial(<function read_excel>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xlsx': functools.partial(<function read_from_bytes>, functools.partial(<function read_excel>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xml': functools.partial(<function read_from_bytes>, <function read_xml>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>)})

Decode a value based on the extension of the key.

### tabled.wrappers.extension_based_encoding(k, v, \*, extension_to_encoder={'arrow': functools.partial(<function written_bytes>, <function dataframe_to_arrow_bytes>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'csv': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_csv>, index=False), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'dta': functools.partial(<function written_bytes>, functools.partial(<function DataFrame.to_stata>, write_index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'feather': functools.partial(<function written_bytes>, <function DataFrame.to_feather>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'gbq': functools.partial(<function written_bytes>, <function \_to_gbq_unavailable>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'h5': functools.partial(<function written_bytes>, <function NDFrame.to_hdf>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'hdf5': functools.partial(<function written_bytes>, <function NDFrame.to_hdf>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'html': functools.partial(<function written_bytes>, functools.partial(<function DataFrame.to_html>, index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'json': functools.partial(<function written_bytes>, <function NDFrame.to_json>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'npy': functools.partial(<function written_bytes>, <function save>, obj_arg_position_in_writer=1, io_buffer_cls=<class '_io.BytesIO'>), 'orc': functools.partial(<function written_bytes>, <function DataFrame.to_orc>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'p': functools.partial(<function written_bytes>, <function NDFrame.to_pickle>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'parquet': functools.partial(<function written_bytes>, <function cast_to_parquet>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'pickle': functools.partial(<function written_bytes>, <function NDFrame.to_pickle>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'pkl': functools.partial(<function written_bytes>, <function NDFrame.to_pickle>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'sql': functools.partial(<function written_bytes>, <function NDFrame.to_sql>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'sqlite': functools.partial(<function written_bytes>, <function NDFrame.to_sql>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'stata': functools.partial(<function written_bytes>, functools.partial(<function DataFrame.to_stata>, write_index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'tsv': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_csv>, index=False, sep='\\t', escapechar='\\\\', quotechar='"'), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'txt': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_csv>, index=False), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'xls': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_excel>, index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'xlsx': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_excel>, index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'xml': functools.partial(<function written_bytes>, <function DataFrame.to_xml>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'zip': <function save_df_to_zipped_tsv>})

Encode a value based on the extension of the key.

### tabled.wrappers.extension_based_wrap(store=None, \*, extension_to_decoder={'arrow': functools.partial(<function read_from_bytes>, <function arrow_bytes_to_dataframe>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'csv': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'dta': functools.partial(<function read_from_bytes>, functools.partial(<function read_stata>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'feather': functools.partial(<function read_from_bytes>, <function read_feather>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'h5': functools.partial(<function read_from_bytes>, <function read_hdf>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'hdf5': functools.partial(<function read_from_bytes>, <function read_hdf>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'html': functools.partial(<function read_from_bytes>, functools.partial(<function read_html>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'json': functools.partial(<function read_from_bytes>, functools.partial(<function read_json>, orient='records'), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'orc': functools.partial(<function read_from_bytes>, <function read_orc>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'p': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'parquet': functools.partial(<function read_from_bytes>, <function read_parquet>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'pickle': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'pkl': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sas': functools.partial(<function read_from_bytes>, <function read_sas>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sav': functools.partial(<function read_from_bytes>, <function read_spss>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sql': functools.partial(<function read_from_bytes>, <function read_sql>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sqlite': functools.partial(<function read_from_bytes>, <function read_sql>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'stata': functools.partial(<function read_from_bytes>, functools.partial(<function read_stata>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'tsv': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, sep='\\t', index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'txt': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xls': functools.partial(<function read_from_bytes>, functools.partial(<function read_excel>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xlsx': functools.partial(<function read_from_bytes>, functools.partial(<function read_excel>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xml': functools.partial(<function read_from_bytes>, <function read_xml>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>)}, extension_to_encoder={'arrow': functools.partial(<function written_bytes>, <function dataframe_to_arrow_bytes>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'csv': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_csv>, index=False), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'dta': functools.partial(<function written_bytes>, functools.partial(<function DataFrame.to_stata>, write_index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'feather': functools.partial(<function written_bytes>, <function DataFrame.to_feather>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'gbq': functools.partial(<function written_bytes>, <function \_to_gbq_unavailable>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'h5': functools.partial(<function written_bytes>, <function NDFrame.to_hdf>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'hdf5': functools.partial(<function written_bytes>, <function NDFrame.to_hdf>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'html': functools.partial(<function written_bytes>, functools.partial(<function DataFrame.to_html>, index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'json': functools.partial(<function written_bytes>, <function NDFrame.to_json>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'npy': functools.partial(<function written_bytes>, <function save>, obj_arg_position_in_writer=1, io_buffer_cls=<class '_io.BytesIO'>), 'orc': functools.partial(<function written_bytes>, <function DataFrame.to_orc>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'p': functools.partial(<function written_bytes>, <function NDFrame.to_pickle>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'parquet': functools.partial(<function written_bytes>, <function cast_to_parquet>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'pickle': functools.partial(<function written_bytes>, <function NDFrame.to_pickle>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'pkl': functools.partial(<function written_bytes>, <function NDFrame.to_pickle>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'sql': functools.partial(<function written_bytes>, <function NDFrame.to_sql>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'sqlite': functools.partial(<function written_bytes>, <function NDFrame.to_sql>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'stata': functools.partial(<function written_bytes>, functools.partial(<function DataFrame.to_stata>, write_index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'tsv': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_csv>, index=False, sep='\\t', escapechar='\\\\', quotechar='"'), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'txt': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_csv>, index=False), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'xls': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_excel>, index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'xlsx': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_excel>, index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'xml': functools.partial(<function written_bytes>, <function DataFrame.to_xml>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'zip': <function save_df_to_zipped_tsv>}, \_\_module_\_=None, \_\_name_\_=None, \_\_qualname_\_=None, \_\_doc_\_=None, \_\_annotations_\_=None, \_\_defaults_\_=None, \_\_kwdefaults_\_=None)

Add extension-based encoding and decoding to a store.

### tabled.wrappers.file_extension(key)

Get the file extension from a key

* **Return type:**
  [`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`Extension`)

```pycon
>>> file_extension('hello.world')
'world'
>>> file_extension('hello')
''
```

### tabled.wrappers.get_codec_mappings(\*, extension_to_encoder={'arrow': functools.partial(<function written_bytes>, <function dataframe_to_arrow_bytes>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'csv': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_csv>, index=False), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'dta': functools.partial(<function written_bytes>, functools.partial(<function DataFrame.to_stata>, write_index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'feather': functools.partial(<function written_bytes>, <function DataFrame.to_feather>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'gbq': functools.partial(<function written_bytes>, <function \_to_gbq_unavailable>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'h5': functools.partial(<function written_bytes>, <function NDFrame.to_hdf>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'hdf5': functools.partial(<function written_bytes>, <function NDFrame.to_hdf>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'html': functools.partial(<function written_bytes>, functools.partial(<function DataFrame.to_html>, index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'json': functools.partial(<function written_bytes>, <function NDFrame.to_json>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'npy': functools.partial(<function written_bytes>, <function save>, obj_arg_position_in_writer=1, io_buffer_cls=<class '_io.BytesIO'>), 'orc': functools.partial(<function written_bytes>, <function DataFrame.to_orc>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'p': functools.partial(<function written_bytes>, <function NDFrame.to_pickle>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'parquet': functools.partial(<function written_bytes>, <function cast_to_parquet>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'pickle': functools.partial(<function written_bytes>, <function NDFrame.to_pickle>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'pkl': functools.partial(<function written_bytes>, <function NDFrame.to_pickle>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'sql': functools.partial(<function written_bytes>, <function NDFrame.to_sql>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'sqlite': functools.partial(<function written_bytes>, <function NDFrame.to_sql>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'stata': functools.partial(<function written_bytes>, functools.partial(<function DataFrame.to_stata>, write_index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'tsv': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_csv>, index=False, sep='\\t', escapechar='\\\\', quotechar='"'), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'txt': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_csv>, index=False), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'xls': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_excel>, index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'xlsx': functools.partial(<function written_bytes>, functools.partial(<function NDFrame.to_excel>, index=True), obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'xml': functools.partial(<function written_bytes>, <function DataFrame.to_xml>, obj_arg_position_in_writer=0, io_buffer_cls=<class '_io.BytesIO'>), 'zip': <function save_df_to_zipped_tsv>}, extension_to_decoder={'arrow': functools.partial(<function read_from_bytes>, <function arrow_bytes_to_dataframe>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'csv': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'dta': functools.partial(<function read_from_bytes>, functools.partial(<function read_stata>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'feather': functools.partial(<function read_from_bytes>, <function read_feather>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'h5': functools.partial(<function read_from_bytes>, <function read_hdf>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'hdf5': functools.partial(<function read_from_bytes>, <function read_hdf>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'html': functools.partial(<function read_from_bytes>, functools.partial(<function read_html>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'json': functools.partial(<function read_from_bytes>, functools.partial(<function read_json>, orient='records'), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'orc': functools.partial(<function read_from_bytes>, <function read_orc>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'p': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'parquet': functools.partial(<function read_from_bytes>, <function read_parquet>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'pickle': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'pkl': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sas': functools.partial(<function read_from_bytes>, <function read_sas>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sav': functools.partial(<function read_from_bytes>, <function read_spss>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sql': functools.partial(<function read_from_bytes>, <function read_sql>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sqlite': functools.partial(<function read_from_bytes>, <function read_sql>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'stata': functools.partial(<function read_from_bytes>, functools.partial(<function read_stata>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'tsv': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, sep='\\t', index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'txt': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xls': functools.partial(<function read_from_bytes>, functools.partial(<function read_excel>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xlsx': functools.partial(<function read_from_bytes>, functools.partial(<function read_excel>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xml': functools.partial(<function read_from_bytes>, <function read_xml>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>)})

Return `{"encoders": extension_to_encoder, "decoders": extension_to_decoder}`.

### tabled.wrappers.get_extension(key)

Return the extension of a file path.

Note that it includes the dot.

* **Return type:**
  [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)

```pycon
>>> get_extension('hello.world')
'.world'
```

If there’s no extension, it returns an empty string.

```pycon
>>> get_extension('hello')
''
```

### tabled.wrappers.get_file_ext(key)

Get the file extension from a key

* **Return type:**
  [`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`Extension`)

```pycon
>>> file_extension('hello.world')
'world'
>>> file_extension('hello')
''
```

### tabled.wrappers.get_protocol(url)

Get the protocol of a url

```pycon
>>> get_protocol('https://www.google.com')
'https'
>>> get_protocol('file:///home/user/file.txt')
'file'
```

The function returns None if no protocol is found:

```pycon
>>> assert get_protocol('no_protocol_here') is None
```

### tabled.wrappers.if_extension_not_present_add_it(filepath, extension)

Append `extension` to `filepath` unless it’s already there.

### tabled.wrappers.if_extension_present_remove_it(filepath, extension)

Strip a trailing `extension` from `filepath`, if present.

### tabled.wrappers.key_func_mapping(obj, mapping, key=<function identity>, not_found_sentinel=Sentinel('dflt_not_found_sentinel'))

Map an object to a value based on a key function

* **Return type:**
  [`TypeVar`](https://docs.python.org/3/library/typing.html#typing.TypeVar)(`VT`)

### tabled.wrappers.map_values(func, d, \*, except_condition=functools.partial(<function \_isinstance>, class_or_tuple=<class 'i2.util.LiteralVal'>), except_handler=operator.methodcaller('_\_call_\_'))

Map values of a dictionary, except for those that satisfy a condition.

The `except_condition` is a function that takes a value and returns a boolean.
If the condition is True, the value is not mapped.
Instead, the `except_handler` is called with the value, and the result is used as
the new value (often, the value is left unchanged).

The default `except_condition` is `is_instance_of(LiteralVal)`, which is a function
that returns True if the value is to be taken litterally.
The default `except_handler` is `methodcaller('__call__')`, which will extract
the litteral value from the `LiteralVal` object.

```pycon
>>> map_values(lambda x: x * 10, {'a': 1, 'b': LiteralVal(2), 'c': 3})
{'a': 10, 'b': 2, 'c': 30}
```

### tabled.wrappers.print_current_mappings()

Print the current extension-to-encoder and extension-to-decoder mappings.

### tabled.wrappers.resolve_to_dataframe(data, ext, ext_mapping={'arrow': functools.partial(<function read_from_bytes>, <function arrow_bytes_to_dataframe>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'csv': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'dta': functools.partial(<function read_from_bytes>, functools.partial(<function read_stata>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'feather': functools.partial(<function read_from_bytes>, <function read_feather>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'h5': functools.partial(<function read_from_bytes>, <function read_hdf>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'hdf5': functools.partial(<function read_from_bytes>, <function read_hdf>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'html': functools.partial(<function read_from_bytes>, functools.partial(<function read_html>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'json': functools.partial(<function read_from_bytes>, functools.partial(<function read_json>, orient='records'), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'orc': functools.partial(<function read_from_bytes>, <function read_orc>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'p': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'parquet': functools.partial(<function read_from_bytes>, <function read_parquet>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'pickle': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'pkl': functools.partial(<function read_from_bytes>, <built-in function load>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sas': functools.partial(<function read_from_bytes>, <function read_sas>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sav': functools.partial(<function read_from_bytes>, <function read_spss>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sql': functools.partial(<function read_from_bytes>, <function read_sql>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'sqlite': functools.partial(<function read_from_bytes>, <function read_sql>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'stata': functools.partial(<function read_from_bytes>, functools.partial(<function read_stata>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'tsv': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, sep='\\\\t', index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'txt': functools.partial(<function read_from_bytes>, functools.partial(<function read_csv>, index_col=None), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xls': functools.partial(<function read_from_bytes>, functools.partial(<function read_excel>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xlsx': functools.partial(<function read_from_bytes>, functools.partial(<function read_excel>, index_col=0), buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>), 'xml': functools.partial(<function read_from_bytes>, <function read_xml>, buffer_arg_position=0, buffer_arg_name=None, io_buffer_cls=<class '_io.BytesIO'>)}, \*\*extra_decoder_kwargs)

Get a dataframe from a (data, ext) pair

* **Return type:**
  `DataFrame`

### tabled.wrappers.save_df_to_zipped_tsv(df, name, sep='\\\\t', index=False, \*\*kwargs)

Save a dataframe to a zipped tsv file.

### tabled.wrappers.single_column_parquet_decode(b, col='_\_single_column_values')

Decode a single-column parquet file into a list of sequences.

#### SEE ALSO
single_column_parquet_encode

```pycon
>>> sequences_2 = [['one', 'two'], ['three', 'four', 'five']]
>>> encoded_2 = single_column_parquet_encode(sequences_2)
>>> decoded_2 = single_column_parquet_decode(encoded_2)
>>> all((x == y).all() for x, y in zip(decoded_2, sequences_2))
True
```

### tabled.wrappers.single_column_parquet_encode(sequences, col='_\_single_column_values')

Encode a list of sequences into a single-column parquet file.
See more general function: cast_to_parquet.

The raison d’etre of this function is to have a two-way codec for sequences->parquet

```pycon
>>> sequences_1 = [[1, 2], [3, 4, 5]]
>>> encoded_1 = single_column_parquet_encode(sequences_1)
>>> decoded_1 = single_column_parquet_decode(encoded_1)
>>> all((x == y).all() for x, y in zip(decoded_1, sequences_1))
True
```


# about-this-build.html.md

<!-- generated by epythet -->

# About this build

This documentation was built on **2026-09-15 13:07 UTC** from commit <a href="https://github.com/i2mint/tabled/commit/2929fedee809938183fe35026702650a1c55a5ca"><code>2929fed</code></a> on branch <code>master</code>, for **tabled 0.1.29** (from <code>pyproject.toml</code>).

#### WARNING
The documentation and the package may be misaligned:

- The documented version (0.1.29) is behind the latest release on PyPI (0.1.30): `pip install tabled` gives newer code than these docs describe.

## Source

|                     |                                                                                                                                                      |
|---------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
| Commit              | <a href="https://github.com/i2mint/tabled/commit/2929fedee809938183fe35026702650a1c55a5ca"><code>2929fedee809938183fe35026702650a1c55a5ca</code></a> |
| Branch              | <code>master</code>                                                                                                                                  |
| Tags at this commit | none                                                                                                                                                 |
| Working tree        | clean                                                                                                                                                |
| Remote              | <code>https://github.com/i2mint/tabled</code>                                                                                                        |

## Continuous integration

|              |                                                                                            |
|--------------|--------------------------------------------------------------------------------------------|
| Repository   | <code>i2mint/tabled</code>                                                                 |
| Run          | <a href="https://github.com/i2mint/tabled/actions/runs/34972839655">34972839655</a>        |
| Ref          | <code>refs/heads/master</code>                                                             |
| Event commit | <code>2929fedee809938183fe35026702650a1c55a5ca</code> (in the history of the built commit) |

## Tools

|          |         |
|----------|---------|
| epythet  | 0.2.12  |
| Sphinx   | 9.1.0   |
| docutils | 0.22.4  |
| Python   | 3.12.14 |

## Configuration as resolved

|               |                                                                  |
|---------------|------------------------------------------------------------------|
| theme         | <code>auto</code> (Sphinx theme <code>shibuya</code>)            |
| accent        | <code>#006292</code>                                             |
| api_generator | <code>autosummary</code>                                         |
| ignore        | <code>tests/</code>, <code>scrap/</code>, <code>examples/</code> |
| agent_outputs | <code>true</code>                                                |
| aggregates    | <code>md</code>                                                  |
| ai_artifacts  | <code>true</code>                                                |

## Package on PyPI

Latest release: <a href="https://pypi.org/project/tabled/0.1.30/">0.1.30</a>, newer than the documented version (0.1.29).

## Reproduce

```bash
git clone https://github.com/i2mint/tabled && cd tabled
git checkout 2929fedee809938183fe35026702650a1c55a5ca
pip install "epythet==0.2.12"
epythet quickstart . --ignore tests/ scrap/ examples/
```

The same data, for machines: <a href="build_info.json"><code>build_info.json</code></a> (schema version 1).


# api.html.md

# API reference

| [`tabled`](_autosummary/tabled.html.md#module-tabled)   | A data-object-layer package for accessing pandas DataFrames from various sources.   |
|-------------------------------------------------------------------------|-------------------------------------------------------------------------------------|


