dataframe-toolkit 0.7.1__tar.gz → 0.7.2__tar.gz
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.
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/PKG-INFO +16 -1
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/README.md +14 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/pyproject.toml +2 -1
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/pyproject.toml.orig +2 -1
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/concat_cmd.py +13 -4
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/fit_cmd.py +19 -5
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/stat_cmd.py +3 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/__init__.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/cli.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/__init__.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/annotate_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/base.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/binx_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/chi_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/clean_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/corr_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/dataset_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/describe_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/eval_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/func_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/help.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/hist_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/info_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/interp_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/line_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/melt_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/merge_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/pivot_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/print_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/query_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/randvar_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/sample_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/scale_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/scat_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/segid_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/split_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/test_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/transpose_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/commands/wstat_cmd.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/common/__init__.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/common/copula.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/common/io.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/common/plot.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/common/seed.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/common/seq.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/common/stats.py +0 -0
- {dataframe_toolkit-0.7.1 → dataframe_toolkit-0.7.2}/src/dftk/io.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: dataframe-toolkit
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.2
|
|
4
4
|
Summary: A command-line toolkit for DataFrame analysis and manipulation
|
|
5
5
|
Keywords: dataframe,statistics,data analysis,CLI,TSV,pandas
|
|
6
6
|
Author: Gunnar Pálsson
|
|
@@ -17,6 +17,7 @@ Requires-Dist: numpy>=1.24
|
|
|
17
17
|
Requires-Dist: pyarrow>=12.0
|
|
18
18
|
Requires-Dist: scipy>=1.10
|
|
19
19
|
Requires-Dist: statsmodels>=0.14
|
|
20
|
+
Requires-Dist: patsy>=0.5.6
|
|
20
21
|
Requires-Dist: duckdb>=0.8
|
|
21
22
|
Requires-Dist: matplotlib>=3.7
|
|
22
23
|
Requires-Dist: seaborn>=0.12
|
|
@@ -73,6 +74,20 @@ cd dataframe-toolkit
|
|
|
73
74
|
uv tool install .
|
|
74
75
|
```
|
|
75
76
|
|
|
77
|
+
### Skill for coding agents
|
|
78
|
+
|
|
79
|
+
`skills/dftk/` is an agent skill: a short guide that coding agents such as
|
|
80
|
+
Codex and Claude Code load when a task involves dftk. It covers the piping
|
|
81
|
+
conventions, which command to use for what, and patterns for Snakemake and
|
|
82
|
+
Make. Copy it into your agent's skills directory, for example:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
cp -r skills/dftk ~/.codex/skills/ # Codex
|
|
86
|
+
cp -r skills/dftk ~/.claude/skills/ # Claude Code
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Copy it again after upgrading dftk so it matches the installed version.
|
|
90
|
+
|
|
76
91
|
## Quick example
|
|
77
92
|
|
|
78
93
|
```bash
|
|
@@ -45,6 +45,20 @@ cd dataframe-toolkit
|
|
|
45
45
|
uv tool install .
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
+
### Skill for coding agents
|
|
49
|
+
|
|
50
|
+
`skills/dftk/` is an agent skill: a short guide that coding agents such as
|
|
51
|
+
Codex and Claude Code load when a task involves dftk. It covers the piping
|
|
52
|
+
conventions, which command to use for what, and patterns for Snakemake and
|
|
53
|
+
Make. Copy it into your agent's skills directory, for example:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
cp -r skills/dftk ~/.codex/skills/ # Codex
|
|
57
|
+
cp -r skills/dftk ~/.claude/skills/ # Claude Code
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Copy it again after upgrading dftk so it matches the installed version.
|
|
61
|
+
|
|
48
62
|
## Quick example
|
|
49
63
|
|
|
50
64
|
```bash
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "dataframe-toolkit"
|
|
3
|
-
version = "0.7.
|
|
3
|
+
version = "0.7.2"
|
|
4
4
|
description = "A command-line toolkit for DataFrame analysis and manipulation"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
keywords = [
|
|
@@ -26,6 +26,7 @@ dependencies = [
|
|
|
26
26
|
"pyarrow>=12.0",
|
|
27
27
|
"scipy>=1.10",
|
|
28
28
|
"statsmodels>=0.14",
|
|
29
|
+
"patsy>=0.5.6",
|
|
29
30
|
"duckdb>=0.8",
|
|
30
31
|
"matplotlib>=3.7",
|
|
31
32
|
"seaborn>=0.12",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "dataframe-toolkit"
|
|
3
|
-
version = "0.7.
|
|
3
|
+
version = "0.7.2"
|
|
4
4
|
description = "A command-line toolkit for DataFrame analysis and manipulation"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [
|
|
@@ -23,6 +23,7 @@ dependencies = [
|
|
|
23
23
|
"pyarrow>=12.0",
|
|
24
24
|
"scipy>=1.10",
|
|
25
25
|
"statsmodels>=0.14",
|
|
26
|
+
"patsy>=0.5.6",
|
|
26
27
|
"duckdb>=0.8",
|
|
27
28
|
"matplotlib>=3.7",
|
|
28
29
|
"seaborn>=0.12",
|
|
@@ -40,6 +40,8 @@ COLUMN ALIGNMENT
|
|
|
40
40
|
----------------
|
|
41
41
|
Columns present in all files are aligned by name.
|
|
42
42
|
Columns missing from some files are filled with NaN (or --fill value).
|
|
43
|
+
--fill applies only to those missing columns: a cell that is empty within
|
|
44
|
+
a file stays empty.
|
|
43
45
|
Use --select to enforce a fixed output column set.
|
|
44
46
|
|
|
45
47
|
EXAMPLES
|
|
@@ -79,7 +81,8 @@ Mismatched columns are outer-joined and filled (NaN by default, or --fill):
|
|
|
79
81
|
metavar="VALUE",
|
|
80
82
|
help=(
|
|
81
83
|
"Fill value for columns absent in some files "
|
|
82
|
-
"(default: NaN). Use 0 or '' for numeric/string defaults."
|
|
84
|
+
"(default: NaN). Use 0 or '' for numeric/string defaults. "
|
|
85
|
+
"Cells that are empty within a file stay empty."
|
|
83
86
|
),
|
|
84
87
|
)
|
|
85
88
|
|
|
@@ -152,8 +155,6 @@ Mismatched columns are outer-joined and filled (NaN by default, or --fill):
|
|
|
152
155
|
if not dfs:
|
|
153
156
|
raise ValueError("concat: no data read from any input file")
|
|
154
157
|
|
|
155
|
-
result = pd.concat(dfs, ignore_index=True)
|
|
156
|
-
|
|
157
158
|
if args.fill is not None:
|
|
158
159
|
fill: int | float | str
|
|
159
160
|
try:
|
|
@@ -163,6 +164,14 @@ Mismatched columns are outer-joined and filled (NaN by default, or --fill):
|
|
|
163
164
|
fill = float(args.fill)
|
|
164
165
|
except ValueError:
|
|
165
166
|
fill = args.fill
|
|
166
|
-
|
|
167
|
+
# Add each file's missing columns before stacking, so --fill
|
|
168
|
+
# touches only those, not cells that were already empty in a file.
|
|
169
|
+
columns = list(dict.fromkeys(c for df in dfs for c in df.columns))
|
|
170
|
+
dfs = [
|
|
171
|
+
df.assign(**{c: fill for c in columns if c not in df.columns})[columns]
|
|
172
|
+
for df in dfs
|
|
173
|
+
]
|
|
174
|
+
|
|
175
|
+
result = pd.concat(dfs, ignore_index=True)
|
|
167
176
|
|
|
168
177
|
io.printdf(result, args)
|
|
@@ -34,10 +34,12 @@ tidy coefficient tables into one output dataframe.
|
|
|
34
34
|
import argparse
|
|
35
35
|
import logging
|
|
36
36
|
|
|
37
|
+
import numpy as np # noqa: F401 — for formulas such as "np.log(y) ~ x", see below
|
|
37
38
|
import pandas as pd
|
|
38
39
|
import statsmodels.api as sm
|
|
39
40
|
import statsmodels.formula.api as smf
|
|
40
41
|
import statsmodels.stats.anova as sa
|
|
42
|
+
from patsy import PatsyError
|
|
41
43
|
|
|
42
44
|
from dftk.commands.base import BaseCommand
|
|
43
45
|
from dftk.common.io import check_cols, io
|
|
@@ -50,6 +52,11 @@ logger = logging.getLogger(__name__)
|
|
|
50
52
|
# ---------------------------------------------------------------------------
|
|
51
53
|
|
|
52
54
|
|
|
55
|
+
# Formulas are evaluated in the namespace of the function that builds the
|
|
56
|
+
# model (statsmodels' default eval_env), i.e. this module's globals — which
|
|
57
|
+
# is why numpy is imported above as np.
|
|
58
|
+
|
|
59
|
+
|
|
53
60
|
def standard_model(df: pd.DataFrame, args: argparse.Namespace):
|
|
54
61
|
"""Return an OLS or RLM (robust) model, not yet fitted."""
|
|
55
62
|
if getattr(args, "robust", False):
|
|
@@ -67,11 +74,18 @@ def weighted_model(df: pd.DataFrame, args: argparse.Namespace):
|
|
|
67
74
|
|
|
68
75
|
|
|
69
76
|
def regress_it(df: pd.DataFrame, args: argparse.Namespace):
|
|
70
|
-
"""Fit the appropriate model and return the fitted result object.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
"""Fit the appropriate model and return the fitted result object.
|
|
78
|
+
|
|
79
|
+
A formula that cannot be evaluated (unknown column or function) raises
|
|
80
|
+
ValueError, which the CLI reports as an input error.
|
|
81
|
+
"""
|
|
82
|
+
try:
|
|
83
|
+
if getattr(args, "weights", None) is not None:
|
|
84
|
+
mod = weighted_model(df, args)
|
|
85
|
+
else:
|
|
86
|
+
mod = standard_model(df, args)
|
|
87
|
+
except PatsyError as exc:
|
|
88
|
+
raise ValueError(f"cannot evaluate formula {args.formula!r}: {exc}") from None
|
|
75
89
|
return mod.fit()
|
|
76
90
|
|
|
77
91
|
|
|
@@ -132,6 +132,9 @@ def _compute_stats(df: pd.DataFrame, args: argparse.Namespace) -> pd.DataFrame:
|
|
|
132
132
|
stats = (
|
|
133
133
|
df[cols].agg(agg_funcs).T.reset_index().rename(columns={"index": "name"})
|
|
134
134
|
)
|
|
135
|
+
# Before the transpose each column held count and the float stats
|
|
136
|
+
# together, so count came out as float; a count is never missing.
|
|
137
|
+
stats["count"] = stats["count"].astype("int64")
|
|
135
138
|
return stats[["name"] + _STAT_NAMES]
|
|
136
139
|
|
|
137
140
|
else:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|