polypress 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,121 @@
1
+ Metadata-Version: 2.4
2
+ Name: polypress
3
+ Version: 0.2.0
4
+ Summary: Lossless compression for data tables, smaller than xz, zstd, brotli and Parquet on coded survey and administrative data
5
+ Author: Mahdi Akbarin
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://www.polypressapp.com
8
+ Project-URL: Repository, https://github.com/potJim80/PolyPressApp
9
+ Keywords: compression,csv,parquet,columnar,survey data
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: System :: Archiving :: Compression
14
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
15
+ Requires-Python: >=3.9
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Requires-Dist: numpy>=1.20
19
+ Provides-Extra: parquet
20
+ Requires-Dist: pyarrow>=8; extra == "parquet"
21
+ Dynamic: license-file
22
+
23
+ # Polypress
24
+
25
+ **A lossless compressor for data tables.** CSV, Parquet, and anything else
26
+ shaped like rows and columns.
27
+
28
+ General-purpose compressors see a table as a stream of bytes. Columnar formats
29
+ see it as columns, and compress each one on its own. Polypress is built on the
30
+ fact that **the columns of a real table are not independent of each other** —
31
+ `City` is nearly determined by `Postal Code`, `latitude` is repeated inside
32
+ `location`, adjacent sensor columns hold nearly the same number — and models
33
+ those relationships directly.
34
+
35
+ The original table comes back **exactly**: same columns, same column order,
36
+ same row order, every cell as the exact string it was.
37
+
38
+ ```sh
39
+ pip install polypress
40
+ polypress compress data.csv # -> data.csv.ppz
41
+ polypress restore data.csv.ppz # -> data.csv
42
+ polypress info data.csv.ppz # plan, shape, how much was reordered
43
+ ```
44
+
45
+ ## The benchmark, and how it was chosen
46
+
47
+ The obvious objection to any compression result is *"you picked the files"*, so
48
+ the main benchmark does not pick. It asks the Socrata open-data catalog for its
49
+ datasets **in descending order of page views** and takes the first 500 that
50
+ pass four mechanical filters (the CSV downloads; at least 2 columns and 20
51
+ rows; at least 50 KB; not a duplicate). Rank order is public and fixed, so the
52
+ list reproduces, and every rejection is recorded with its reason.
53
+
54
+ **500 tables, 3.57 GB of CSV, 14.3 million rows, 10,557 columns**, against 17
55
+ competing codecs:
56
+
57
+ | | |
58
+ |---|---|
59
+ | Round-trips exactly | **500 of 500** |
60
+ | Smaller than the best of all 17 competitors | **478 of 500** |
61
+ | Margin over the best other tool | median **1.25x**, best 2.73x, worst 0.65x |
62
+ | Compression vs raw CSV | median **14.35x** |
63
+
64
+ Head to head: it beats `xz -9e`, `zstd -22`, `gzip -9` and `lz4 -9` on **all
65
+ 500**; `parquet+zstd` on 449 of 450; `bzip2 -9` on 491 of 500; `brotli -q 11`
66
+ on 487 of 500.
67
+
68
+ **Two things belong next to those numbers.** Parquet, read with type inference,
69
+ reproduced the exact printed text on only 81 of the 500 tables — turning
70
+ `"1.50"` into `1.5` makes a smaller file for reasons that have nothing to do
71
+ with compression, and Polypress guarantees the printed cell. And the margin is
72
+ not a better final compressor: re-finishing the same modelled streams with the
73
+ competitor's own entropy coder still wins 449 of 450 against `parquet+zstd`.
74
+
75
+ ## How it works
76
+
77
+ 1. **Predict down a column.** Fit a low-degree polynomial to the last few
78
+ values, extrapolate one step, store the error. Re-centring the fit at every
79
+ cell means the coefficients never have to be stored — order-*k*
80
+ extrapolation is exactly the *k*-th finite difference.
81
+ 2. **The same thing in two dimensions.** Where adjacent numeric columns are
82
+ *commensurable*, a cell is predicted from its left, upper and upper-left
83
+ neighbours. This is what wins on matrix-shaped tables, and no shipped
84
+ columnar codec does it — Gorilla, DoubleDelta, T64, zfp and fpzip all
85
+ predict down a single column.
86
+ 3. **Reorder the rows so a column collapses into runs.** Rather than model that
87
+ `City` depends on `Postal Code`, sort by the parent: equal parents become
88
+ adjacent and the child collapses. **The permutation is free** — the decoder
89
+ has already rebuilt the parent and recomputes the same stable sort. Your
90
+ table comes back in its original row order.
91
+
92
+ ## What it is honest about
93
+
94
+ - **It is slow to compress.** Median 2.0 MB/s encode, 134 MB/s decode. The
95
+ never-worse guarantee is what costs it: eligible tables are encoded twice and
96
+ the smaller result wins.
97
+ - **The core idea is not novel.** US 8,312,026 B2 (Vo, AT&T, filed 2009)
98
+ discloses it. It was arrived at here independently and the novelty claim was
99
+ withdrawn. Both relevant patents have expired.
100
+ - **The 2x results are matrix-shaped tables.** 1.3–1.5x is typical, and
101
+ text-heavy tables are the weak genre.
102
+ - **All 22 losses out of 500 are published**, including the one genuine
103
+ undiagnosed loss.
104
+ - **Every benchmark dataset is a government open-data table.** There is no
105
+ reason to assume the result transfers to other genres.
106
+ - **Nobody outside the project has run it.**
107
+
108
+ ## Requirements
109
+
110
+ Python 3.9+ and numpy. A C compiler is optional — the accelerator compiles
111
+ itself on first import and falls back to numpy without one. `pyarrow` is
112
+ needed only for `.parquet` input and output: `pip install 'polypress[parquet]'`.
113
+
114
+ ## More
115
+
116
+ Source, tests, the full benchmark harness and the committed sweep results:
117
+ **https://github.com/potJim80/PolyPressApp** — including `memory/LAWS.md`, the
118
+ findings that govern what gets built, and the README section listing everything
119
+ that was tried and failed.
120
+
121
+ MIT licensed.
@@ -0,0 +1,15 @@
1
+ polypress/__init__.py,sha256=wo-1RDT5el4Ra_iF0azwVAhQDZnu9myJs9LUp756rhE,477
2
+ polypress/caccel.py,sha256=7l7LR22be8GpIYpa-13Nx6B54V5XRtf43h83dXWSAuU,5471
3
+ polypress/cli.py,sha256=vNF7hlmdUfFx4Uxb9rA_FijC_kV1ONu-SfqaWy8lD14,9922
4
+ polypress/codec.py,sha256=z8DZ5LWA-Ri67OL6nfXMdVaahNhH1WVH1wagLSdEg8o,9904
5
+ polypress/dtz.py,sha256=sNYYPYbPt_Ky0tGydLWt1lOSzEBFAbPwYunp33DfVqg,34800
6
+ polypress/fast.py,sha256=cD0m7K7lPZQGO0zXIY_gVICgpaTBLgR6OzDPqNOou-o,58551
7
+ polypress/stream.py,sha256=CLXWqfvDW-r0LaG7jCwdoFU8pK3wnVfGtiZJAgYBQVw,15832
8
+ polypress/tcz.c,sha256=sNlSit2eYzZPdFfPTHGM55Rl-0Zi0xYk3krvX70DI50,7357
9
+ polypress/turbo.py,sha256=xzvYgXBX9D4DzKTqcxVmq4YRD2AmYsKo9HEnrs-hlPI,63160
10
+ polypress-0.2.0.dist-info/licenses/LICENSE,sha256=dzEqVzuWEUSE2lOUbeaCgxHUMtohs4O_WeBLe6hrB70,1070
11
+ polypress-0.2.0.dist-info/METADATA,sha256=LdjKaprJRFF8l-qnLpOrPWyRWdxs8Pl78pqKiSn4l9U,5561
12
+ polypress-0.2.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
13
+ polypress-0.2.0.dist-info/entry_points.txt,sha256=DI8n7uEWagVuaUdc_eb0OyK-wRyRtrjkQAIL91ur01s,49
14
+ polypress-0.2.0.dist-info/top_level.txt,sha256=j-bQ0QOAfEB1hzvrb0gVFUTicSSGS89znrvQ2zI0Lfc,10
15
+ polypress-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ polypress = polypress.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mahdi Akbarin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ polypress