EHN: allow zip compression in `to_pickle`, `to_json`, `to_csv`
State: closed

- [x] closes https://github.com/pandas-dev/pandas/issues/17778
- [x] tests added / passed
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [x] whatsnew entry

Currently, `to_pickle` doesn't support compression='zip' whereas `read_pickle` is able to unpickle zip compressed file. The same applies to `to_json`, `to_csv` methods under generic, frame, series. 

Standard library ZipFile class default write method requires a filename but pickle.dump(obj, f, protocol) requires f being a file-like object (i.e. file handle) which offers writing bytes. Create a new BytesZipFile class that allows pickle.dump to write bytes into zip file handle. 

Now zip compressed objects (pickle, json, csv) are roundtripable with `read_pickle`, `read_json`, `read_csv`.

Need suggestion as to where to put BytesZipFile class which overrides `write` method with `writestr`. Other comments welcome.

Labels:
name: Bug
name: IO Data
description: IO issues that don't fit into a more specific label

Comments:
# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/20394?src=pr&el=h1) Report
> Merging [#20394](https://codecov.io/gh/pandas-dev/pandas/pull/20394?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/7273ea0709590e6264607f227bb8def0ef656c50?src=pr&el=desc) will **increase** coverage by `0.01%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/pandas-dev/pandas/pull/20394/graphs/tree.svg?height=150&width=650&token=eZ4WkYLtcO&src=pr)](https://codecov.io/gh/pandas-dev/pandas/pull/20394?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master   #20394      +/-   ##
==========================================
+ Coverage   91.77%   91.79%   +0.01%     
==========================================
  Files         152      152              
  Lines       49205    49233      +28     
==========================================
+ Hits        45159    45191      +32     
+ Misses       4046     4042       -4
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `90.17% <100%> (+0.01%)` | :arrow_up: |
| #single | `41.84% <19.23%> (-0.02%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/20394?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/generic.py](https://codecov.io/gh/pandas-dev/pandas/pull/20394/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZ2VuZXJpYy5weQ==) | `95.85% <ø> (ø)` | :arrow_up: |
| [pandas/core/frame.py](https://codecov.io/gh/pandas-dev/pandas/pull/20394/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZnJhbWUucHk=) | `97.18% <ø> (ø)` | :arrow_up: |
| [pandas/util/testing.py](https://codecov.io/gh/pandas-dev/pandas/pull/20394/diff?src=pr&el=tree#diff-cGFuZGFzL3V0aWwvdGVzdGluZy5weQ==) | `84.52% <ø> (+0.57%)` | :arrow_up: |
| [pandas/core/series.py](https://codecov.io/gh/pandas-dev/pandas/pull/20394/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvc2VyaWVzLnB5) | `93.84% <ø> (ø)` | :arrow_up: |
| [pandas/io/formats/csvs.py](https://codecov.io/gh/pandas-dev/pandas/pull/20394/diff?src=pr&el=tree#diff-cGFuZGFzL2lvL2Zvcm1hdHMvY3N2cy5weQ==) | `98.13% <100%> (+0.08%)` | :arrow_up: |
| [pandas/io/common.py](https://codecov.io/gh/pandas-dev/pandas/pull/20394/diff?src=pr&el=tree#diff-cGFuZGFzL2lvL2NvbW1vbi5weQ==) | `70.04% <100%> (+1.26%)` | :arrow_up: |
| [pandas/core/window.py](https://codecov.io/gh/pandas-dev/pandas/pull/20394/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvd2luZG93LnB5) | `96.26% <0%> (-0.01%)` | :arrow_down: |
| [pandas/core/panel.py](https://codecov.io/gh/pandas-dev/pandas/pull/20394/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvcGFuZWwucHk=) | `97.29% <0%> (ø)` | :arrow_up: |
| ... and [9 more](https://codecov.io/gh/pandas-dev/pandas/pull/20394/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/20394?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/20394?src=pr&el=footer). Last update [7273ea0...ebd8e6f](https://codecov.io/gh/pandas-dev/pandas/pull/20394?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

ensure_clean() somehow fails to randomize on one of the 2.7 configuration with xdist. strange.

when pickle seems to work different in Python 2 and not seem to be way around it. making zip compression only available for Python>=3.x
zip compression for pickle now should work in Python 2 now as well as Python 3, so does zip compression for json.

However, csv zip compression works only in Python 3, not Python 2.
zip compression now should work both read/write for pickle, json, csv in Python 2/3.

@jreback all changes implemented. further comments welcome.
@jreback @jorisvandenbossche any comments on this PR?
@gfyoung @jreback any comments?
thanks @minggli keep em coming!