dataframe-toolkit 0.4.1__tar.gz → 0.5.1__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.
Files changed (44) hide show
  1. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/PKG-INFO +76 -38
  2. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/README.md +75 -37
  3. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/pyproject.toml +1 -1
  4. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/__init__.py +6 -3
  5. dataframe_toolkit-0.5.1/src/dftk/commands/info_cmd.py +74 -0
  6. dataframe_toolkit-0.5.1/src/dftk/commands/segid_cmd.py +118 -0
  7. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/stat_cmd.py +10 -5
  8. dataframe_toolkit-0.5.1/src/dftk/commands/transpose_cmd.py +57 -0
  9. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/__init__.py +0 -0
  10. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/cli.py +0 -0
  11. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/annotate_cmd.py +0 -0
  12. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/base.py +0 -0
  13. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/binx_cmd.py +0 -0
  14. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/clean_cmd.py +0 -0
  15. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/concat_cmd.py +0 -0
  16. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/corr_cmd.py +0 -0
  17. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/dataset_cmd.py +0 -0
  18. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/describe_cmd.py +0 -0
  19. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/eval_cmd.py +0 -0
  20. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/fit_cmd.py +0 -0
  21. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/func_cmd.py +0 -0
  22. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/help.py +0 -0
  23. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/hist_cmd.py +0 -0
  24. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/interp_cmd.py +0 -0
  25. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/line_cmd.py +0 -0
  26. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/melt_cmd.py +0 -0
  27. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/merge_cmd.py +0 -0
  28. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/pivot_cmd.py +0 -0
  29. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/print_cmd.py +0 -0
  30. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/query_cmd.py +0 -0
  31. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/randvar_cmd.py +0 -0
  32. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/sample_cmd.py +0 -0
  33. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/scale_cmd.py +0 -0
  34. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/scat_cmd.py +0 -0
  35. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/split_cmd.py +0 -0
  36. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/test_cmd.py +0 -0
  37. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/commands/wstat_cmd.py +0 -0
  38. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/common/__init__.py +0 -0
  39. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/common/io.py +0 -0
  40. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/common/plot.py +0 -0
  41. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/common/seed.py +0 -0
  42. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/common/seq.py +0 -0
  43. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/common/stats.py +0 -0
  44. {dataframe_toolkit-0.4.1 → dataframe_toolkit-0.5.1}/src/dftk/io.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dataframe-toolkit
3
- Version: 0.4.1
3
+ Version: 0.5.1
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
@@ -38,6 +38,14 @@ for analysts who live in the terminal and want a consistent, pipeable toolkit
38
38
  for the full data analysis pipeline — from initial exploration through
39
39
  statistical modelling and publication-quality figures.
40
40
 
41
+ **No data file handy?** Every example below uses `dftk dataset` to pull in a
42
+ small, real dataset, so you can copy-paste any of them and run them right
43
+ now. Run `dftk dataset --list` to browse everything available (dozens of
44
+ datasets from seaborn, statsmodels, and pydataset). `dftk dataset NAME`
45
+ searches all three sources in that order and returns the first match, so
46
+ `--source` is optional — pass it only to disambiguate a name that exists in
47
+ more than one source, or to restrict the search.
48
+
41
49
  ## Installation
42
50
 
43
51
  ```bash
@@ -68,28 +76,38 @@ uv tool install .
68
76
  ## Quick example
69
77
 
70
78
  ```bash
71
- dftk stat data.tsv -c height weight -g sex
72
- dftk stat data.tsv -c value -g group -o \
73
- | dftk pivot -i group -v value_mean -o \
74
- | dftk print
79
+ dftk dataset tips | dftk stat - -c tip total_bill -g day
80
+ ```
81
+
82
+ Chain commands with `-o` (write to a temp parquet, print its path) and `...`
83
+ (read a parquet path from stdin) instead of piping TSV text directly — faster
84
+ for large data, and the recommended pattern once a pipeline has more than one
85
+ step:
86
+
87
+ ```bash
88
+ dftk dataset tips -o \
89
+ | dftk pivot ... -i day -v tip -f mean -o \
90
+ | dftk print ...
75
91
  ```
76
92
 
77
93
  ## Subcommands
78
94
 
79
95
  ### Data transformation
80
96
 
81
- | Command | Description |
82
- |-----------|--------------------------------------------------------------------------------------|
83
- | `eval` | Add or modify columns: eval expressions, string/path functions, statistical ops |
84
- | `query` | Filter rows with pandas query expressions or SQL (`--sql` via DuckDB) |
85
- | `merge` | Join two tables on key columns (inner/left/right/outer) |
86
- | `concat` | Concatenate two or more tables row-wise |
87
- | `melt` | Reshape wide-to-long (`pd.melt`) |
88
- | `pivot` | Reshape long-to-wide with per-cell aggregation |
89
- | `func` | Column transforms: cumsum, group mean/sum/min/max/count/median/std, rank, qcut:N |
90
- | `scale` | Normalise: z-score, min-shift, sum/max/mean scaling, Blom rank, regression residuals |
91
- | `interp` | Interpolate values from a reference curve into a table (1-D lookup) |
92
- | `binx` | Assign bin indices to a column based on explicit or generated edges |
97
+ | Command | Description |
98
+ |-------------|---------------------------------------------------------------------------------------|
99
+ | `eval` | Add or modify columns: eval expressions, string/path functions, statistical ops |
100
+ | `query` | Filter rows with pandas query expressions or SQL (`--sql` via DuckDB) |
101
+ | `merge` | Join two tables on key columns (inner/left/right/outer) |
102
+ | `concat` | Concatenate two or more tables row-wise |
103
+ | `melt` | Reshape wide-to-long (`pd.melt`) |
104
+ | `pivot` | Reshape long-to-wide with per-cell aggregation |
105
+ | `func` | Column transforms: cumsum, group mean/sum/min/max/count/median/std, rank, qcut:N |
106
+ | `scale` | Normalise: z-score, min-shift, sum/max/mean scaling, Blom rank, regression residuals |
107
+ | `interp` | Interpolate values from a reference curve into a table (1-D lookup) |
108
+ | `binx` | Assign bin indices to a column based on explicit or generated edges |
109
+ | `transpose` | Flip rows and columns; original column names land in a new `--keycol` column |
110
+ | `segid` | Assign a segment ID that increments on each value change in a column |
93
111
 
94
112
  ### Statistics
95
113
 
@@ -101,6 +119,7 @@ dftk stat data.tsv -c value -g group -o \
101
119
  | `test` | P-values between column pairs: t-test, Mann-Whitney, Wilcoxon, KS, correlations, bootstrap; groups |
102
120
  | `corr` | Pairwise column correlations (Pearson/Spearman/Kendall) with optional BCa bootstrap CI |
103
121
  | `describe` | Quick column-level summary (dtype, n, n_unique, n_null, sample values) |
122
+ | `info` | Per-column dtype, null counts, and memory usage; `--summary` for dataset-level totals |
104
123
  | `randvar` | Sample from a distribution and append as a new column (norm, alpha, beta, …) |
105
124
 
106
125
  ### Plots
@@ -133,38 +152,48 @@ publication-quality output.
133
152
  ### Chaining commands
134
153
 
135
154
  ```bash
136
- # z-score within group, then fit a model
137
- dftk scale data.tsv -c expr -g condition -o \
138
- | dftk fit - -f "expr_z ~ time + batch" -g condition
155
+ # z-score sepal_length within species, then fit against petal_length
156
+ dftk dataset iris -o \
157
+ | dftk scale ... -c sepal_length -g species -o \
158
+ | dftk fit ... -f "sepal_length_scaled ~ petal_length" -g species
139
159
  ```
140
160
 
141
161
  ### Group summary then plot
142
162
 
143
163
  ```bash
144
- dftk stat results.tsv -c value -g group -o \
145
- | dftk line - -x group -y value_mean --yerr value_sem -f fig.png
164
+ dftk dataset tips -o \
165
+ | dftk stat ... -c tip -g day -o \
166
+ | dftk line ... -x day -y mean --yerr sem -f fig.png
146
167
  ```
147
168
 
148
169
  ### Wide-to-long then plot overlaid histograms
149
170
 
150
171
  ```bash
151
- dftk melt data.tsv -i sample -d gene -v expression \
152
- | dftk hist - -x expression -g gene -k -f dist.png
172
+ dftk dataset iris \
173
+ | dftk melt - -i species -d measurement -v value \
174
+ | dftk hist - -x value -g measurement -k -f dist.png
153
175
  ```
154
176
 
155
177
  ### Interpolation (standard curve lookup)
156
178
 
157
179
  ```bash
158
- dftk interp samples.tsv --ref stdcurve.tsv \
159
- -x fluorescence -v concentration -d conc_ng_ul
180
+ printf "conc\tfluor\n0\t5\n10\t52\n20\t98\n30\t151\n" > stdcurve.tsv
181
+ printf "sample\tfluor\ns1\t60\ns2\t110\n" \
182
+ | dftk interp - --ref stdcurve.tsv -x fluor --refx fluor -v conc -d conc_ng_ul
160
183
  ```
161
184
 
162
185
  ### Bootstrap confidence intervals
163
186
 
187
+ Bootstrap mode repeats the full stat computation N times on resampled data
188
+ and emits one row per resample (tagged with `samplenum`) — pipe into `pivot`
189
+ with percentile aggfuncs (`cilo`/`cihi`) to collapse that into an empirical
190
+ confidence interval:
191
+
164
192
  ```bash
165
- dftk stat data.tsv -c value -g group --bootstrap 1000 --randomseed 42 -o \
166
- | dftk pivot -i group -v value_mean -f mean -o \
167
- | dftk stat - -c group_A group_B
193
+ dftk dataset tips -o \
194
+ | dftk stat ... -c tip -g day --bootstrap 1000 --randomseed 42 -o \
195
+ | dftk pivot ... -i day -v mean -f mean cilo cihi -o \
196
+ | dftk print ...
168
197
  ```
169
198
 
170
199
  ## Input/output
@@ -176,9 +205,19 @@ All commands accept:
176
205
  - `...` to receive a parquet path from stdin (written by a previous `-o` command)
177
206
  - A `.parquet` filename to read a named parquet file directly
178
207
 
208
+ > **`-` vs `...`** — these are not interchangeable. Use `-` when the previous
209
+ > command in the pipe wrote plain TSV to stdout (the default). Use `...` when
210
+ > the previous command used bare `-o` (pipe mode), which writes a temp
211
+ > parquet and prints *its path* to stdout — `-` would try to parse that path
212
+ > as TSV and fail.
213
+
179
214
  Standard output options (available on all tabular commands):
180
215
 
181
- - `-o` / `--output` — write a temp parquet for the next piped command instead of TSV to stdout
216
+ - `-o` / `--output` — controls where output goes; takes an *optional* value:
217
+ - `-o` alone — write a temp parquet to pipe into the next command, printing its path to stdout (auto-deleted once read)
218
+ - `-o FILE.parquet` — write a named, reusable parquet, printing its path to stdout
219
+ - `-o FILE` (no `.parquet` extension) — write TSV to `FILE`, with no stdout output
220
+ - omit `-o` entirely — write TSV to stdout (the default)
182
221
  - `--select col1 col2 …` — keep only these columns
183
222
  - `--drop col1 col2 …` — remove these columns
184
223
  - `--round N` — round numeric output
@@ -193,20 +232,19 @@ any new `--meta` values.
193
232
 
194
233
  ```bash
195
234
  # Tag a file at creation
196
- dftk eval raw.tsv -f "z = x + y" -o results.parquet \
197
- --meta genome=hg38 --meta source=gwas_2024
235
+ dftk dataset iris -o iris.parquet --meta source=seaborn --meta species_col=species
198
236
 
199
237
  # Inspect annotations
200
- dftk annotate results.parquet
201
- # genome hg38
202
- # source gwas_2024
238
+ dftk annotate iris.parquet
239
+ # source seaborn
240
+ # species_col species
203
241
 
204
242
  # Add or update an annotation in-place
205
- dftk annotate results.parquet --set step=qc_filtered
243
+ dftk annotate iris.parquet --set step=raw
206
244
 
207
245
  # Annotations survive piping
208
- dftk eval results.parquet -f "z_scaled = z / 2" -o | dftk scale ... -c z -o scaled.parquet
209
- dftk annotate scaled.parquet # genome and source still present
246
+ dftk eval iris.parquet -f "petal_area = petal_length * petal_width" -o iris2.parquet
247
+ dftk annotate iris2.parquet # source, species_col, and step all still present
210
248
  ```
211
249
 
212
250
  ## Figure options (plot commands)
@@ -10,6 +10,14 @@ for analysts who live in the terminal and want a consistent, pipeable toolkit
10
10
  for the full data analysis pipeline — from initial exploration through
11
11
  statistical modelling and publication-quality figures.
12
12
 
13
+ **No data file handy?** Every example below uses `dftk dataset` to pull in a
14
+ small, real dataset, so you can copy-paste any of them and run them right
15
+ now. Run `dftk dataset --list` to browse everything available (dozens of
16
+ datasets from seaborn, statsmodels, and pydataset). `dftk dataset NAME`
17
+ searches all three sources in that order and returns the first match, so
18
+ `--source` is optional — pass it only to disambiguate a name that exists in
19
+ more than one source, or to restrict the search.
20
+
13
21
  ## Installation
14
22
 
15
23
  ```bash
@@ -40,28 +48,38 @@ uv tool install .
40
48
  ## Quick example
41
49
 
42
50
  ```bash
43
- dftk stat data.tsv -c height weight -g sex
44
- dftk stat data.tsv -c value -g group -o \
45
- | dftk pivot -i group -v value_mean -o \
46
- | dftk print
51
+ dftk dataset tips | dftk stat - -c tip total_bill -g day
52
+ ```
53
+
54
+ Chain commands with `-o` (write to a temp parquet, print its path) and `...`
55
+ (read a parquet path from stdin) instead of piping TSV text directly — faster
56
+ for large data, and the recommended pattern once a pipeline has more than one
57
+ step:
58
+
59
+ ```bash
60
+ dftk dataset tips -o \
61
+ | dftk pivot ... -i day -v tip -f mean -o \
62
+ | dftk print ...
47
63
  ```
48
64
 
49
65
  ## Subcommands
50
66
 
51
67
  ### Data transformation
52
68
 
53
- | Command | Description |
54
- |-----------|--------------------------------------------------------------------------------------|
55
- | `eval` | Add or modify columns: eval expressions, string/path functions, statistical ops |
56
- | `query` | Filter rows with pandas query expressions or SQL (`--sql` via DuckDB) |
57
- | `merge` | Join two tables on key columns (inner/left/right/outer) |
58
- | `concat` | Concatenate two or more tables row-wise |
59
- | `melt` | Reshape wide-to-long (`pd.melt`) |
60
- | `pivot` | Reshape long-to-wide with per-cell aggregation |
61
- | `func` | Column transforms: cumsum, group mean/sum/min/max/count/median/std, rank, qcut:N |
62
- | `scale` | Normalise: z-score, min-shift, sum/max/mean scaling, Blom rank, regression residuals |
63
- | `interp` | Interpolate values from a reference curve into a table (1-D lookup) |
64
- | `binx` | Assign bin indices to a column based on explicit or generated edges |
69
+ | Command | Description |
70
+ |-------------|---------------------------------------------------------------------------------------|
71
+ | `eval` | Add or modify columns: eval expressions, string/path functions, statistical ops |
72
+ | `query` | Filter rows with pandas query expressions or SQL (`--sql` via DuckDB) |
73
+ | `merge` | Join two tables on key columns (inner/left/right/outer) |
74
+ | `concat` | Concatenate two or more tables row-wise |
75
+ | `melt` | Reshape wide-to-long (`pd.melt`) |
76
+ | `pivot` | Reshape long-to-wide with per-cell aggregation |
77
+ | `func` | Column transforms: cumsum, group mean/sum/min/max/count/median/std, rank, qcut:N |
78
+ | `scale` | Normalise: z-score, min-shift, sum/max/mean scaling, Blom rank, regression residuals |
79
+ | `interp` | Interpolate values from a reference curve into a table (1-D lookup) |
80
+ | `binx` | Assign bin indices to a column based on explicit or generated edges |
81
+ | `transpose` | Flip rows and columns; original column names land in a new `--keycol` column |
82
+ | `segid` | Assign a segment ID that increments on each value change in a column |
65
83
 
66
84
  ### Statistics
67
85
 
@@ -73,6 +91,7 @@ dftk stat data.tsv -c value -g group -o \
73
91
  | `test` | P-values between column pairs: t-test, Mann-Whitney, Wilcoxon, KS, correlations, bootstrap; groups |
74
92
  | `corr` | Pairwise column correlations (Pearson/Spearman/Kendall) with optional BCa bootstrap CI |
75
93
  | `describe` | Quick column-level summary (dtype, n, n_unique, n_null, sample values) |
94
+ | `info` | Per-column dtype, null counts, and memory usage; `--summary` for dataset-level totals |
76
95
  | `randvar` | Sample from a distribution and append as a new column (norm, alpha, beta, …) |
77
96
 
78
97
  ### Plots
@@ -105,38 +124,48 @@ publication-quality output.
105
124
  ### Chaining commands
106
125
 
107
126
  ```bash
108
- # z-score within group, then fit a model
109
- dftk scale data.tsv -c expr -g condition -o \
110
- | dftk fit - -f "expr_z ~ time + batch" -g condition
127
+ # z-score sepal_length within species, then fit against petal_length
128
+ dftk dataset iris -o \
129
+ | dftk scale ... -c sepal_length -g species -o \
130
+ | dftk fit ... -f "sepal_length_scaled ~ petal_length" -g species
111
131
  ```
112
132
 
113
133
  ### Group summary then plot
114
134
 
115
135
  ```bash
116
- dftk stat results.tsv -c value -g group -o \
117
- | dftk line - -x group -y value_mean --yerr value_sem -f fig.png
136
+ dftk dataset tips -o \
137
+ | dftk stat ... -c tip -g day -o \
138
+ | dftk line ... -x day -y mean --yerr sem -f fig.png
118
139
  ```
119
140
 
120
141
  ### Wide-to-long then plot overlaid histograms
121
142
 
122
143
  ```bash
123
- dftk melt data.tsv -i sample -d gene -v expression \
124
- | dftk hist - -x expression -g gene -k -f dist.png
144
+ dftk dataset iris \
145
+ | dftk melt - -i species -d measurement -v value \
146
+ | dftk hist - -x value -g measurement -k -f dist.png
125
147
  ```
126
148
 
127
149
  ### Interpolation (standard curve lookup)
128
150
 
129
151
  ```bash
130
- dftk interp samples.tsv --ref stdcurve.tsv \
131
- -x fluorescence -v concentration -d conc_ng_ul
152
+ printf "conc\tfluor\n0\t5\n10\t52\n20\t98\n30\t151\n" > stdcurve.tsv
153
+ printf "sample\tfluor\ns1\t60\ns2\t110\n" \
154
+ | dftk interp - --ref stdcurve.tsv -x fluor --refx fluor -v conc -d conc_ng_ul
132
155
  ```
133
156
 
134
157
  ### Bootstrap confidence intervals
135
158
 
159
+ Bootstrap mode repeats the full stat computation N times on resampled data
160
+ and emits one row per resample (tagged with `samplenum`) — pipe into `pivot`
161
+ with percentile aggfuncs (`cilo`/`cihi`) to collapse that into an empirical
162
+ confidence interval:
163
+
136
164
  ```bash
137
- dftk stat data.tsv -c value -g group --bootstrap 1000 --randomseed 42 -o \
138
- | dftk pivot -i group -v value_mean -f mean -o \
139
- | dftk stat - -c group_A group_B
165
+ dftk dataset tips -o \
166
+ | dftk stat ... -c tip -g day --bootstrap 1000 --randomseed 42 -o \
167
+ | dftk pivot ... -i day -v mean -f mean cilo cihi -o \
168
+ | dftk print ...
140
169
  ```
141
170
 
142
171
  ## Input/output
@@ -148,9 +177,19 @@ All commands accept:
148
177
  - `...` to receive a parquet path from stdin (written by a previous `-o` command)
149
178
  - A `.parquet` filename to read a named parquet file directly
150
179
 
180
+ > **`-` vs `...`** — these are not interchangeable. Use `-` when the previous
181
+ > command in the pipe wrote plain TSV to stdout (the default). Use `...` when
182
+ > the previous command used bare `-o` (pipe mode), which writes a temp
183
+ > parquet and prints *its path* to stdout — `-` would try to parse that path
184
+ > as TSV and fail.
185
+
151
186
  Standard output options (available on all tabular commands):
152
187
 
153
- - `-o` / `--output` — write a temp parquet for the next piped command instead of TSV to stdout
188
+ - `-o` / `--output` — controls where output goes; takes an *optional* value:
189
+ - `-o` alone — write a temp parquet to pipe into the next command, printing its path to stdout (auto-deleted once read)
190
+ - `-o FILE.parquet` — write a named, reusable parquet, printing its path to stdout
191
+ - `-o FILE` (no `.parquet` extension) — write TSV to `FILE`, with no stdout output
192
+ - omit `-o` entirely — write TSV to stdout (the default)
154
193
  - `--select col1 col2 …` — keep only these columns
155
194
  - `--drop col1 col2 …` — remove these columns
156
195
  - `--round N` — round numeric output
@@ -165,20 +204,19 @@ any new `--meta` values.
165
204
 
166
205
  ```bash
167
206
  # Tag a file at creation
168
- dftk eval raw.tsv -f "z = x + y" -o results.parquet \
169
- --meta genome=hg38 --meta source=gwas_2024
207
+ dftk dataset iris -o iris.parquet --meta source=seaborn --meta species_col=species
170
208
 
171
209
  # Inspect annotations
172
- dftk annotate results.parquet
173
- # genome hg38
174
- # source gwas_2024
210
+ dftk annotate iris.parquet
211
+ # source seaborn
212
+ # species_col species
175
213
 
176
214
  # Add or update an annotation in-place
177
- dftk annotate results.parquet --set step=qc_filtered
215
+ dftk annotate iris.parquet --set step=raw
178
216
 
179
217
  # Annotations survive piping
180
- dftk eval results.parquet -f "z_scaled = z / 2" -o | dftk scale ... -c z -o scaled.parquet
181
- dftk annotate scaled.parquet # genome and source still present
218
+ dftk eval iris.parquet -f "petal_area = petal_length * petal_width" -o iris2.parquet
219
+ dftk annotate iris2.parquet # source, species_col, and step all still present
182
220
  ```
183
221
 
184
222
  ## Figure options (plot commands)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "dataframe-toolkit"
3
- version = "0.4.1"
3
+ version = "0.5.1"
4
4
  description = "A command-line toolkit for DataFrame analysis and manipulation"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -18,6 +18,7 @@ from dftk.commands.fit_cmd import FitCommand
18
18
  from dftk.commands.func_cmd import FuncCommand
19
19
  from dftk.commands.help import HelpCommand
20
20
  from dftk.commands.hist_cmd import HistCommand
21
+ from dftk.commands.info_cmd import InfoCommand
21
22
  from dftk.commands.interp_cmd import InterpCommand
22
23
  from dftk.commands.line_cmd import LineCommand
23
24
  from dftk.commands.melt_cmd import MeltCommand
@@ -29,15 +30,14 @@ from dftk.commands.randvar_cmd import RandvarCommand
29
30
  from dftk.commands.sample_cmd import SampleCommand
30
31
  from dftk.commands.scale_cmd import ScaleCommand
31
32
  from dftk.commands.scat_cmd import ScatCommand
33
+ from dftk.commands.segid_cmd import SegidCommand
32
34
  from dftk.commands.split_cmd import SplitCommand
33
35
  from dftk.commands.stat_cmd import StatCommand
34
36
  from dftk.commands.test_cmd import TestCommand
37
+ from dftk.commands.transpose_cmd import TransposeCommand
35
38
  from dftk.commands.wstat_cmd import WstatCommand
36
39
 
37
40
  # Ported subcommands — uncomment as each one is added:
38
- # from dftk.commands.segid import SegidCommand
39
- # from dftk.commands.info import InfoCommand
40
- # from dftk.commands.transpose import TransposeCommand
41
41
  # from dftk.commands.color import ColorCommand
42
42
  # from dftk.commands.wavelet import WaveletCommand
43
43
  # from dftk.commands.fisher import FisherCommand # superseded by eval's
@@ -57,6 +57,8 @@ COMMAND_GROUPS: list[tuple[str, list]] = [
57
57
  ScaleCommand(),
58
58
  InterpCommand(),
59
59
  BinxCommand(),
60
+ TransposeCommand(),
61
+ SegidCommand(),
60
62
  ],
61
63
  ),
62
64
  (
@@ -68,6 +70,7 @@ COMMAND_GROUPS: list[tuple[str, list]] = [
68
70
  TestCommand(),
69
71
  CorrCommand(),
70
72
  DescribeCommand(),
73
+ InfoCommand(),
71
74
  RandvarCommand(),
72
75
  ],
73
76
  ),
@@ -0,0 +1,74 @@
1
+ """
2
+ dftk.commands.info_cmd — dftk info subcommand.
3
+
4
+ Lightweight structural overview of a DataFrame: per-column dtype, null
5
+ counts, and memory usage. Complements `describe`, which profiles
6
+ statistical distributions and quality flags instead.
7
+
8
+ Example
9
+ -------
10
+ dftk info data.tsv
11
+ dftk info data.tsv --summary
12
+ """
13
+
14
+ import argparse
15
+ import sys
16
+
17
+ import pandas as pd
18
+
19
+ from dftk.commands.base import BaseCommand
20
+ from dftk.common.io import io
21
+
22
+
23
+ def _info(df: pd.DataFrame) -> pd.DataFrame:
24
+ mem = df.memory_usage(deep=True, index=False)
25
+ return pd.DataFrame(
26
+ [
27
+ dict(
28
+ name=col,
29
+ dtype=str(df[col].dtype),
30
+ non_null=int(df[col].notna().sum()),
31
+ null=int(df[col].isna().sum()),
32
+ memory_bytes=int(mem[col]),
33
+ )
34
+ for col in df.columns
35
+ ]
36
+ )
37
+
38
+
39
+ def _summary_line(df: pd.DataFrame) -> str:
40
+ n_rows, n_cols = df.shape
41
+ total_mem = int(df.memory_usage(deep=True).sum())
42
+ n_dupes = int(df.duplicated().sum())
43
+ return (
44
+ f"Dataset: {n_rows} rows x {n_cols} columns, "
45
+ f"{total_mem} bytes, {n_dupes} duplicated row(s)"
46
+ )
47
+
48
+
49
+ class InfoCommand(BaseCommand):
50
+ @property
51
+ def name(self) -> str:
52
+ return "info"
53
+
54
+ @property
55
+ def help(self) -> str:
56
+ return "Structural overview: per-column dtype, null counts, memory usage"
57
+
58
+ def add_arguments(self, parser: argparse.ArgumentParser) -> None:
59
+ self.add_io_arguments(parser)
60
+
61
+ g = parser.add_argument_group("info options")
62
+ g.add_argument(
63
+ "--summary",
64
+ action="store_true",
65
+ help="Print dataset totals (shape, memory, duplicate rows) to stderr.",
66
+ )
67
+
68
+ def execute(self, args: argparse.Namespace) -> None:
69
+ df = io.read(args)
70
+
71
+ if getattr(args, "summary", False):
72
+ print(_summary_line(df), file=sys.stderr)
73
+
74
+ io.printdf(_info(df), args)
@@ -0,0 +1,118 @@
1
+ """
2
+ dftk.commands.segid_cmd — dftk segid subcommand.
3
+
4
+ Port of dfsegid.py: assign a segment ID that increments each time the
5
+ value in a column changes, useful for grouping contiguous runs of
6
+ identical values (e.g. constant-value stretches in a sorted column).
7
+
8
+ Rows matching --ignore are excluded from the run comparison and always get
9
+ segid 0; they don't break a run spanning across them. Redesigned from the
10
+ legacy script's magic sentinel default ('1415926535', digits of pi) to a
11
+ plain optional flag — omit --ignore to include every row.
12
+ """
13
+
14
+ import argparse
15
+
16
+ import pandas as pd
17
+
18
+ from dftk.commands.base import BaseCommand
19
+ from dftk.common.io import check_cols, io
20
+
21
+ _EPILOG = """\
22
+ EXAMPLE
23
+ -------
24
+ col
25
+ A
26
+ A
27
+ B
28
+ B
29
+ A
30
+
31
+ dftk segid data.tsv -c col
32
+
33
+ col segid
34
+ A 1
35
+ A 1
36
+ B 2
37
+ B 2
38
+ A 3
39
+
40
+ With --ignore X, rows where col == X get segid 0 and are skipped when
41
+ detecting value changes, so a run continues across them:
42
+
43
+ col
44
+ A
45
+ X
46
+ A
47
+ B
48
+
49
+ dftk segid data.tsv -c col --ignore X
50
+
51
+ col segid
52
+ A 1
53
+ X 0
54
+ A 1
55
+ B 2
56
+ """
57
+
58
+
59
+ def _segid(df: pd.DataFrame, args: argparse.Namespace) -> pd.DataFrame:
60
+ col = args.col
61
+ dest = args.destcol
62
+
63
+ df[dest] = 0
64
+
65
+ if args.ignore is not None:
66
+ ignore_value = pd.Series([args.ignore]).astype(df[col].dtype).iloc[0]
67
+ mask = df[col] != ignore_value
68
+ else:
69
+ mask = pd.Series(True, index=df.index)
70
+
71
+ subseries = df.loc[mask, col]
72
+ df.loc[mask, dest] = subseries.ne(subseries.shift()).cumsum()
73
+ return df
74
+
75
+
76
+ class SegidCommand(BaseCommand):
77
+ @property
78
+ def name(self) -> str:
79
+ return "segid"
80
+
81
+ @property
82
+ def help(self) -> str:
83
+ return "Assign a segment ID that increments on each value change"
84
+
85
+ def add_arguments(self, parser: argparse.ArgumentParser) -> None:
86
+ parser.formatter_class = argparse.RawDescriptionHelpFormatter
87
+ parser.epilog = _EPILOG
88
+
89
+ self.add_io_arguments(parser)
90
+
91
+ g = parser.add_argument_group("segid options")
92
+ g.add_argument(
93
+ "-c",
94
+ "--col",
95
+ required=True,
96
+ metavar="COL",
97
+ help="Column whose value changes define segment boundaries.",
98
+ )
99
+ g.add_argument(
100
+ "-d",
101
+ "--destcol",
102
+ default="segid",
103
+ metavar="DESTCOL",
104
+ help="Name of the output segment-ID column (default: segid).",
105
+ )
106
+ g.add_argument(
107
+ "--ignore",
108
+ default=None,
109
+ metavar="VALUE",
110
+ help="Column value to exclude from segmenting (gets segid 0, "
111
+ "doesn't break a run spanning across it). Default: none.",
112
+ )
113
+
114
+ def execute(self, args: argparse.Namespace) -> None:
115
+ df = io.read(args)
116
+ check_cols(df, [args.col], "-c/--col")
117
+ result = _segid(df, args)
118
+ io.printdf(result, args)
@@ -21,9 +21,11 @@ into ``dftk pivot`` to aggregate across samples.
21
21
  Example
22
22
  -------
23
23
  dftk stat data.tsv -c height weight -g sex
24
+
25
+ # Empirical bootstrap CI: resample, then collapse with percentile aggfuncs
24
26
  dftk stat data.tsv -c value -g group --bootstrap 1000 --randomseed 42 -o \\
25
- | dftk pivot -i group -v value_mean -o \\
26
- | dftk print
27
+ | dftk pivot ... -i group -v mean -f mean cilo cihi -o \\
28
+ | dftk print ...
27
29
  """
28
30
 
29
31
  import argparse
@@ -278,9 +280,12 @@ class StatCommand(BaseCommand):
278
280
  if args.groupcol is None:
279
281
  sample = df.sample(**sample_kwargs)
280
282
  else:
281
- sample = df.groupby(args.groupcol, group_keys=False).apply(
282
- lambda x: x.sample(**sample_kwargs)
283
- )
283
+ # [df.columns.tolist()] re-selection works around a pandas 3.0
284
+ # groupby(...).apply() change that otherwise drops the
285
+ # grouping column from the result.
286
+ sample = df.groupby(args.groupcol, group_keys=False)[
287
+ df.columns.tolist()
288
+ ].apply(lambda x: x.sample(**sample_kwargs))
284
289
 
285
290
  result = _compute_stats(sample, args)
286
291
  result["samplenum"] = i
@@ -0,0 +1,57 @@
1
+ """
2
+ dftk.commands.transpose_cmd — dftk transpose subcommand.
3
+
4
+ Port of dftpos.py: flips rows and columns. Original column names become
5
+ values in a new key column (default name: "column"); original row
6
+ positions become the new column headers.
7
+
8
+ Example
9
+ -------
10
+ Input:
11
+
12
+ sample x y
13
+ s1 1 2
14
+ s2 3 4
15
+
16
+ dftk transpose data.tsv
17
+
18
+ Output:
19
+
20
+ column 0 1
21
+ sample s1 s2
22
+ x 1 3
23
+ y 2 4
24
+ """
25
+
26
+ import argparse
27
+
28
+ from dftk.commands.base import BaseCommand
29
+ from dftk.common.io import io
30
+
31
+
32
+ class TransposeCommand(BaseCommand):
33
+ @property
34
+ def name(self) -> str:
35
+ return "transpose"
36
+
37
+ @property
38
+ def help(self) -> str:
39
+ return "Transpose rows and columns"
40
+
41
+ def add_arguments(self, parser: argparse.ArgumentParser) -> None:
42
+ self.add_io_arguments(parser)
43
+
44
+ g = parser.add_argument_group("transpose options")
45
+ g.add_argument(
46
+ "--keycol",
47
+ default="column",
48
+ metavar="NAME",
49
+ help="Name for the new column holding the original column names "
50
+ "(default: column).",
51
+ )
52
+
53
+ def execute(self, args: argparse.Namespace) -> None:
54
+ df = io.read(args)
55
+ result = df.transpose().reset_index(names=args.keycol)
56
+ result.columns = [str(c) for c in result.columns]
57
+ io.printdf(result, args)