sudo pip install numexpr
    sudo pip install tables

    References:
        https://pytables.github.io/cookbook/py2exe_howto.html
        https://gist.github.com/andrewgiessel/7515520
        http://stackoverflow.com/questions/8843062/python-how-to-store-a-numpy-multidimensional-array-in-pytables
        http://pytables.github.io/usersguide/tutorials.html#creating-new-array-objects

    Example:
        >>> # DISABLE_DOCTEST
        >>> from utool.util_io import *  # NOQA
        >>> import numpy as np
        >>> import utool as ut
        >>> # build test data
        >>> verbose = True
        >>> fpath = 'myfile.pytables.hdf5'
        >>> np.random.seed(0)
        >>> compression = 'gzip'
        >>> data = (np.random.rand(100000, 128) * 255).astype(np.uint8).copy()
        >>> # execute function
        >>> ut.delete(fpath)
        >>> save_pytables(fpath, data, verbose)
        >>> data2 = load_pytables(fpath, verbose)
        >>> assert data is not data2
        >>> assert np.all(data == data2)
        >>> assert ut.delete(fpath)

def save_pytables(fpath, data, verbose=False):
    """
    sudo pip install numexpr
    sudo pip install tables

    References:
        https://pytables.github.io/cookbook/py2exe_howto.html
        https://gist.github.com/andrewgiessel/7515520
        http://stackoverflow.com/questions/8843062/python-how-to-store-a-numpy-multidimensional-array-in-pytables
        http://pytables.github.io/usersguide/tutorials.html#creating-new-array-objects

    Example:
        >>> # DISABLE_DOCTEST
        >>> from utool.util_io import *  # NOQA
        >>> import numpy as np
        >>> import utool as ut
        >>> # build test data
        >>> verbose = True
        >>> fpath = 'myfile.pytables.hdf5'
        >>> np.random.seed(0)
        >>> compression = 'gzip'
        >>> data = (np.random.rand(100000, 128) * 255).astype(np.uint8).copy()
        >>> # execute function
        >>> ut.delete(fpath)
        >>> save_pytables(fpath, data, verbose)
        >>> data2 = load_pytables(fpath, verbose)
        >>> assert data is not data2
        >>> assert np.all(data == data2)
        >>> assert ut.delete(fpath)
    """
    import tables
    #from os.path import basename
    #fname = basename(fpath)
    #shape = data.shape
    #dtype = data.dtype
    #file_ = tables.open_file(fpath)
    verbose = _rectify_verb_write(verbose)
    if verbose:
        print('[util_io] * save_pytables(%r, data)' % (util_path.tail(fpath),))
    with tables.open_file(fpath, 'w') as file_:
        atom = tables.Atom.from_dtype(data.dtype)
        filters = tables.Filters(complib='blosc', complevel=5)
        dset = file_.createCArray(file_.root, 'data', atom, data.shape, filters=filters)
        # save w/o compressive filter
        #dset = file_.createCArray(file_.root, 'all_data', atom, all_data.shape)
        dset[:] = data