### Has anyone ever efficiently serialized/deserialized a pandas SparseDataFrame?

```
import pandas as pd
import scipy
from scipy import sparse
dfs = pd.SparseDataFrame(scipy.sparse.random(1000, 1000).toarray())
# just for testing

```

### pickle is not an answer

It's outrageously slow.

```
import pickle, time
start = time.time()
# serialization
msg = list(pickle.dumps(dfs, protocol=pickle.HIGHEST_PROTOCOL))
# deserialization
dfs = pickle.loads(bytes(msg))
stop = time.time()
stop - start
# 0.4420337677001953
# This is with Python 3.5 so it's using cPickle

```

As a comparison msgpack is faster *on the dense version*

```
df = dfs.to_dense()
start = time.time()
# serialization
msg = list(df.to_msgpack(compress='zlib'))
# deserialization
df = pd.read_msgpack(bytes(msg))
stop = time.time()
stop - start
# 0.09514737129211426

```

### msgpack

Msgpack would be the answer but I can't find an implementation for SparseDataFrame ([related](https://github.com/pandas-dev/pandas/issues/23119))

```
# serialization
dfs.to_msgpack(compress='zlib')
# Returns: NotImplementedError: msgpack sparse frame is not implemented

```

### coordinate format

msgpack on a coordinate format via `scipy.sparse.coo_matrix` seems to be worth considering but conversion to `python.sparse.coo_matrix` is slow

```
from scipy.sparse import coo_matrix
start = time.time()

# serialization
columns = dfs.columns
shape = dfs.shape
start_to_coo = time.time()
dfc = dfs.to_coo()
stop_to_coo = time.time()
start_comprehension = time.time()
row = [x.item() for x in df.row]
col = [x.item() for x in df.col]
data = [x.item() for x in df.data]
stop_comprehension = time.time()
start_packing = time.time()
msg = list(msgpack.packb({'columns':list(columns), 'shape':shape, 'row':row, 'col':col, 'data':data}))
stop_packing = time.time()

# deserialization
start_unpacking = time.time()
dict = msgpack.unpackb(bytes(msg))
stop_unpacking = time.time()
columns=dict[b'columns']
index=range(dict[b'shape'][0])
dfc = coo_matrix((dict[b'data'], (dict[b'row'], dict[b'col'])), shape=dict[b'shape'])

stop = time.time()
print('total: ' + str(stop - start))
print('  to_coo: ' + str(stop_to_coo - start_to_coo))
print('  comprehension: ' + str(stop_comprehension - start_comprehension))
print('  packing: ' + str(stop_packing - start_packing))
print('  unpacking: ' + str(stop_unpacking - start_unpacking))

#total: 0.2799222469329834
#  to_coo:               0.22925591468811035
#  comprehension & cast: 0.02356100082397461 (msgpack does not support all numpy formats)
#  packing:              0.004893064498901367
#  unpacking:            0.001984834671020508

```

From there it seems one needs to go through a dense format.

```
start = time.time()
dfs = pd.SparseDataFrame(dfc.toarray())
stop = time.time()
stop - start
# 2.8947737216949463

```