dataframe-textual 1.0.0__py3-none-any.whl → 1.4.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.
- dataframe_textual/__init__.py +1 -2
- dataframe_textual/__main__.py +48 -23
- dataframe_textual/common.py +372 -23
- dataframe_textual/data_frame_help_panel.py +6 -4
- dataframe_textual/data_frame_table.py +893 -449
- dataframe_textual/data_frame_viewer.py +39 -141
- dataframe_textual/sql_screen.py +202 -0
- dataframe_textual/table_screen.py +45 -28
- dataframe_textual/yes_no_screen.py +12 -8
- {dataframe_textual-1.0.0.dist-info → dataframe_textual-1.4.0.dist-info}/METADATA +205 -46
- dataframe_textual-1.4.0.dist-info/RECORD +14 -0
- {dataframe_textual-1.0.0.dist-info → dataframe_textual-1.4.0.dist-info}/entry_points.txt +1 -0
- dataframe_textual-1.0.0.dist-info/RECORD +0 -13
- {dataframe_textual-1.0.0.dist-info → dataframe_textual-1.4.0.dist-info}/WHEEL +0 -0
- {dataframe_textual-1.0.0.dist-info → dataframe_textual-1.4.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -33,9 +33,11 @@ class YesNoScreen(ModalScreen):
|
|
|
33
33
|
min-width: 40;
|
|
34
34
|
max-width: 60;
|
|
35
35
|
height: auto;
|
|
36
|
-
border: heavy $
|
|
37
|
-
border-title-color: $
|
|
38
|
-
background: $
|
|
36
|
+
border: heavy $accent;
|
|
37
|
+
border-title-color: $accent;
|
|
38
|
+
border-title-background: $panel;
|
|
39
|
+
border-title-style: bold;
|
|
40
|
+
background: $background;
|
|
39
41
|
padding: 1 2;
|
|
40
42
|
}
|
|
41
43
|
|
|
@@ -241,6 +243,7 @@ class YesNoScreen(ModalScreen):
|
|
|
241
243
|
yield self.no
|
|
242
244
|
|
|
243
245
|
def on_button_pressed(self, event: Button.Pressed) -> None:
|
|
246
|
+
"""Handle button press events in the Yes/No screen."""
|
|
244
247
|
if event.button.id == "yes":
|
|
245
248
|
self._handle_yes()
|
|
246
249
|
elif event.button.id == "maybe":
|
|
@@ -249,6 +252,7 @@ class YesNoScreen(ModalScreen):
|
|
|
249
252
|
self.dismiss(None)
|
|
250
253
|
|
|
251
254
|
def on_key(self, event) -> None:
|
|
255
|
+
"""Handle key press events in the table screen."""
|
|
252
256
|
if event.key == "enter":
|
|
253
257
|
self._handle_yes()
|
|
254
258
|
event.stop()
|
|
@@ -298,7 +302,7 @@ class SaveFileScreen(YesNoScreen):
|
|
|
298
302
|
|
|
299
303
|
|
|
300
304
|
class ConfirmScreen(YesNoScreen):
|
|
301
|
-
"""Modal screen to
|
|
305
|
+
"""Modal screen to ask for confirmation."""
|
|
302
306
|
|
|
303
307
|
CSS = YesNoScreen.DEFAULT_CSS.replace("YesNoScreen", "ConfirmScreen")
|
|
304
308
|
|
|
@@ -582,7 +586,7 @@ class AddColumnScreen(YesNoScreen):
|
|
|
582
586
|
title="Add Column",
|
|
583
587
|
label="Enter column name",
|
|
584
588
|
input="column name",
|
|
585
|
-
label2="Enter value or Polars expression, e.g., 123, NULL, $_ * 2",
|
|
589
|
+
label2="Enter value or Polars expression, e.g., abc, pl.lit(123), NULL, $_ * 2, $1 + $2, $_.str.to_uppercase(), pl.concat_str($_, pl.lit('-suffix'))",
|
|
586
590
|
input2="column value or expression",
|
|
587
591
|
on_yes_callback=self._get_input,
|
|
588
592
|
)
|
|
@@ -609,7 +613,7 @@ class AddColumnScreen(YesNoScreen):
|
|
|
609
613
|
return self.cidx, col_name, pl.lit(None)
|
|
610
614
|
elif tentative_expr(term):
|
|
611
615
|
try:
|
|
612
|
-
expr = validate_expr(term, self.df, self.cidx)
|
|
616
|
+
expr = validate_expr(term, self.df.columns, self.cidx)
|
|
613
617
|
return self.cidx, col_name, expr
|
|
614
618
|
except ValueError as e:
|
|
615
619
|
self.notify(f"Invalid expression [$error]{term}[/]: {str(e)}", title="Add Column", severity="error")
|
|
@@ -634,10 +638,10 @@ class FindReplaceScreen(YesNoScreen):
|
|
|
634
638
|
|
|
635
639
|
CSS = YesNoScreen.DEFAULT_CSS.replace("YesNoScreen", "ReplaceScreen")
|
|
636
640
|
|
|
637
|
-
def __init__(self, dftable: DataFrameTable):
|
|
641
|
+
def __init__(self, dftable: "DataFrameTable", title: str = "Find and Replace"):
|
|
638
642
|
term_find = str(dftable.cursor_value)
|
|
639
643
|
super().__init__(
|
|
640
|
-
title=
|
|
644
|
+
title=title,
|
|
641
645
|
label="Find",
|
|
642
646
|
input=term_find,
|
|
643
647
|
label2="Replace with",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dataframe-textual
|
|
3
|
-
Version: 1.
|
|
4
|
-
Summary: Interactive
|
|
3
|
+
Version: 1.4.0
|
|
4
|
+
Summary: Interactive terminal viewer/editor for tabular data
|
|
5
5
|
Project-URL: Homepage, https://github.com/need47/dataframe-textual
|
|
6
6
|
Project-URL: Repository, https://github.com/need47/dataframe-textual.git
|
|
7
7
|
Project-URL: Documentation, https://github.com/need47/dataframe-textual#readme
|
|
@@ -9,7 +9,7 @@ Project-URL: Bug Tracker, https://github.com/need47/dataframe-textual/issues
|
|
|
9
9
|
Author-email: Tiejun Cheng <need47@gmail.com>
|
|
10
10
|
License: MIT
|
|
11
11
|
License-File: LICENSE
|
|
12
|
-
Keywords: csv,data-analysis,excel,interactive,polars,terminal,textual,tui,viewer
|
|
12
|
+
Keywords: csv,data-analysis,editor,excel,interactive,polars,terminal,textual,tui,viewer
|
|
13
13
|
Classifier: Development Status :: 3 - Alpha
|
|
14
14
|
Classifier: Environment :: Console
|
|
15
15
|
Classifier: Intended Audience :: Developers
|
|
@@ -29,7 +29,7 @@ Classifier: Topic :: Utilities
|
|
|
29
29
|
Classifier: Typing :: Typed
|
|
30
30
|
Requires-Python: >=3.11
|
|
31
31
|
Requires-Dist: polars>=1.34.0
|
|
32
|
-
Requires-Dist: textual>=
|
|
32
|
+
Requires-Dist: textual[syntax]>=6.5.0
|
|
33
33
|
Provides-Extra: dev
|
|
34
34
|
Requires-Dist: textual-dev>=1.8.0; extra == 'dev'
|
|
35
35
|
Provides-Extra: excel
|
|
@@ -45,11 +45,11 @@ A powerful, interactive terminal-based viewer/editor for CSV/TSV/Excel/Parquet/J
|
|
|
45
45
|
|
|
46
46
|
## Features
|
|
47
47
|
|
|
48
|
-
###
|
|
48
|
+
### Data Viewing
|
|
49
49
|
- 🚀 **Fast Loading** - Powered by Polars for efficient data handling
|
|
50
|
-
- 🎨 **Rich Terminal UI** - Beautiful, color-coded columns with
|
|
50
|
+
- 🎨 **Rich Terminal UI** - Beautiful, color-coded columns with various data types (e.g., integer, float, string)
|
|
51
51
|
- ⌨️ **Comprehensive Keyboard Navigation** - Intuitive controls for browsing, editing, and manipulating data
|
|
52
|
-
- 📊 **Flexible Input** - Read from files or stdin (pipes/redirects)
|
|
52
|
+
- 📊 **Flexible Input** - Read from files and/or stdin (pipes/redirects)
|
|
53
53
|
- 🔄 **Smart Pagination** - Lazy load rows on demand for handling large datasets
|
|
54
54
|
|
|
55
55
|
### Data Manipulation
|
|
@@ -60,7 +60,7 @@ A powerful, interactive terminal-based viewer/editor for CSV/TSV/Excel/Parquet/J
|
|
|
60
60
|
- 💾 **Save & Undo** - Save edits back to file with full undo/redo support
|
|
61
61
|
|
|
62
62
|
### Advanced Features
|
|
63
|
-
- 📂 **Multi-File Support** - Open multiple files in tabs
|
|
63
|
+
- 📂 **Multi-File Support** - Open multiple files in separate tabs
|
|
64
64
|
- 🔄 **Tab Management** - Seamlessly switch between open files with keyboard shortcuts
|
|
65
65
|
- 📌 **Freeze Rows/Columns** - Keep important rows and columns visible while scrolling
|
|
66
66
|
- 🎯 **Cursor Type Cycling** - Switch between cell, row, and column selection modes
|
|
@@ -77,9 +77,11 @@ pip install dataframe-textual
|
|
|
77
77
|
pip install dataframe-textual[excel]
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
+
This installs an executable `dv`.
|
|
81
|
+
|
|
80
82
|
Then run:
|
|
81
83
|
```bash
|
|
82
|
-
|
|
84
|
+
dv <csv_file>
|
|
83
85
|
```
|
|
84
86
|
|
|
85
87
|
### Using [uv](https://docs.astral.sh/uv/)
|
|
@@ -90,9 +92,10 @@ uvx https://github.com/need47/dataframe-textual.git <csvfile>
|
|
|
90
92
|
|
|
91
93
|
# Clone or download the project
|
|
92
94
|
cd dataframe-textual
|
|
95
|
+
uv sync --extra excel # with Excel support
|
|
93
96
|
|
|
94
97
|
# Run directly with uv
|
|
95
|
-
uv run
|
|
98
|
+
uv run dv <csv_file>
|
|
96
99
|
```
|
|
97
100
|
|
|
98
101
|
### Development installation
|
|
@@ -115,7 +118,7 @@ pip install -e ".[excel,dev]"
|
|
|
115
118
|
|
|
116
119
|
```bash
|
|
117
120
|
# After pip install dataframe-textual
|
|
118
|
-
|
|
121
|
+
dv pokemon.csv
|
|
119
122
|
|
|
120
123
|
# Or if running from source
|
|
121
124
|
python main.py pokemon.csv
|
|
@@ -124,21 +127,31 @@ python main.py pokemon.csv
|
|
|
124
127
|
uv run python main.py pokemon.csv
|
|
125
128
|
|
|
126
129
|
# Read from stdin (auto-detects format; defaults to TSV if not recognized)
|
|
127
|
-
cat data.tsv |
|
|
128
|
-
|
|
130
|
+
cat data.tsv | dv
|
|
131
|
+
dv < data.tsv
|
|
132
|
+
|
|
133
|
+
# Gzipped files are supported
|
|
134
|
+
dv data.csv.gz
|
|
135
|
+
dv large_dataset.tsv.gz
|
|
136
|
+
|
|
137
|
+
# Specify format for gzipped stdin
|
|
138
|
+
zcat data.csv.gz | dv -f csv
|
|
129
139
|
```
|
|
130
140
|
|
|
131
141
|
### Multi-File Usage - Multiple Tabs
|
|
132
142
|
|
|
133
143
|
```bash
|
|
134
144
|
# Open multiple files in tabs
|
|
135
|
-
|
|
145
|
+
dv file1.csv file2.csv file3.csv
|
|
136
146
|
|
|
137
147
|
# Open multiple sheets in tabs in an Excel file
|
|
138
|
-
|
|
148
|
+
dv file.xlsx
|
|
139
149
|
|
|
140
150
|
# Mix files and stdin (read from stdin, then open file)
|
|
141
|
-
|
|
151
|
+
dv data1.tsv < data2.tsv
|
|
152
|
+
|
|
153
|
+
# Mix regular and gzipped files
|
|
154
|
+
dv data1.csv data2.csv.gz data3.tsv.gz
|
|
142
155
|
```
|
|
143
156
|
|
|
144
157
|
When multiple files are opened:
|
|
@@ -148,6 +161,67 @@ When multiple files are opened:
|
|
|
148
161
|
- Close the current tab with `Ctrl+W`
|
|
149
162
|
- Each file maintains its own state (edits, sort order, selections, history, etc.)
|
|
150
163
|
|
|
164
|
+
## Command Line Options
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
usage: dv [-h] [-f {csv,excel,tsv,parquet,json,ndjson}] [-H] [-I] [-L SKIP_LINES] [-K SKIP_ROWS_AFTER_HEADER] [-U NULL [NULL ...]] [files ...]
|
|
168
|
+
|
|
169
|
+
Interactive terminal based viewer/editor for tabular data (e.g., CSV/Excel).
|
|
170
|
+
|
|
171
|
+
positional arguments:
|
|
172
|
+
files Files to view (or read from stdin)
|
|
173
|
+
|
|
174
|
+
options:
|
|
175
|
+
-h, --help show this help message and exit
|
|
176
|
+
-f, --format {csv,excel,tsv,parquet,json,ndjson}
|
|
177
|
+
Specify the format of the input files
|
|
178
|
+
-H, --no-header Specify that input files have no header row
|
|
179
|
+
-I, --no-inferrence Do not infer data types when reading CSV/TSV
|
|
180
|
+
-L, --skip-lines SKIP_LINES
|
|
181
|
+
Skip lines when reading CSV/TSV (default: 0)
|
|
182
|
+
-K, --skip-rows-after-header SKIP_ROWS_AFTER_HEADER
|
|
183
|
+
Skip rows after header when reading CSV/TSV (default: 0)
|
|
184
|
+
-U, --null NULL [NULL ...]
|
|
185
|
+
Values to interpret as null values when reading CSV/TSV
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### CLI Examples
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
# View CSV file without header row
|
|
192
|
+
dv -H data_no_header.csv
|
|
193
|
+
|
|
194
|
+
# Disable type inference for faster loading
|
|
195
|
+
dv -I large_data.csv
|
|
196
|
+
|
|
197
|
+
# Skip first 3 lines of file (e.g., comments, metadata)
|
|
198
|
+
dv -L 3 data_with_comments.csv
|
|
199
|
+
|
|
200
|
+
# Skip 1 row after header (e.g., units row)
|
|
201
|
+
dv -K 1 data_with_units.csv
|
|
202
|
+
|
|
203
|
+
# Treat specific values as null/missing (e.g., 'NA', 'N/A', '-')
|
|
204
|
+
dv -U NA N/A - data.csv
|
|
205
|
+
|
|
206
|
+
# Multiple null values with different formats
|
|
207
|
+
dv -U NULL NA "" "Not Available" messy_data.csv
|
|
208
|
+
|
|
209
|
+
# Complex CSV with comments and units row
|
|
210
|
+
dv -L 3 -K 1 -I messy_scientific_data.csv
|
|
211
|
+
|
|
212
|
+
# Combine all options: skip lines, skip after header, no header, no inference, gzipped
|
|
213
|
+
dv -L 2 -K 1 -H -I complex_data.csv.gz
|
|
214
|
+
|
|
215
|
+
# Process compressed data from stdin with line skipping
|
|
216
|
+
zcat compressed_data.csv.gz | dv -f csv -L 2
|
|
217
|
+
|
|
218
|
+
# CSV with custom null values and no header
|
|
219
|
+
dv -H -U NA "N/A" "-" raw_data.csv
|
|
220
|
+
|
|
221
|
+
# Skip lines, specify null values, and disable type inference
|
|
222
|
+
dv -L 5 -U NA "" data_with_metadata.csv
|
|
223
|
+
```
|
|
224
|
+
|
|
151
225
|
## Keyboard Shortcuts
|
|
152
226
|
|
|
153
227
|
### App-Level Controls
|
|
@@ -158,7 +232,7 @@ When multiple files are opened:
|
|
|
158
232
|
|-----|--------|
|
|
159
233
|
| `Ctrl+O` | Open file in a new tab |
|
|
160
234
|
| `Ctrl+W` | Close current tab |
|
|
161
|
-
| `Ctrl+
|
|
235
|
+
| `Ctrl+A` | Save all open tabs to Excel file |
|
|
162
236
|
| `>` or `b` | Move to next tab |
|
|
163
237
|
| `<` | Move to previous tab |
|
|
164
238
|
| `B` | Toggle tab bar visibility |
|
|
@@ -168,7 +242,7 @@ When multiple files are opened:
|
|
|
168
242
|
|
|
169
243
|
| Key | Action |
|
|
170
244
|
|-----|--------|
|
|
171
|
-
| `
|
|
245
|
+
| `F1` | Toggle help panel |
|
|
172
246
|
| `k` | Cycle through themes |
|
|
173
247
|
|
|
174
248
|
---
|
|
@@ -186,6 +260,8 @@ When multiple files are opened:
|
|
|
186
260
|
| `Home` / `End` | Jump to first/last column in current row |
|
|
187
261
|
| `Ctrl + Home` / `Ctrl + End` | Jump to top/bottom in current page |
|
|
188
262
|
| `PageDown` / `PageUp` | Scroll down/up one page |
|
|
263
|
+
| `Ctrl+F` | Page down |
|
|
264
|
+
| `Ctrl+B` | Page up |
|
|
189
265
|
|
|
190
266
|
#### Viewing & Display
|
|
191
267
|
|
|
@@ -197,23 +273,26 @@ When multiple files are opened:
|
|
|
197
273
|
| `S` | Show statistics for entire dataframe |
|
|
198
274
|
| `K` | Cycle cursor type: cell → row → column → cell |
|
|
199
275
|
| `~` | Toggle row labels |
|
|
276
|
+
| `_` (underscore) | Expand column to full width |
|
|
200
277
|
|
|
201
278
|
#### Data Editing
|
|
202
279
|
|
|
203
280
|
| Key | Action |
|
|
204
281
|
|-----|--------|
|
|
205
282
|
| `Double-click` | Edit cell or rename column header |
|
|
206
|
-
| `
|
|
283
|
+
| `delete` | Clear current cell (set to NULL) |
|
|
207
284
|
| `e` | Edit current cell (respects data type) |
|
|
208
285
|
| `E` | Edit entire column with expression |
|
|
209
286
|
| `a` | Add empty column after current |
|
|
210
287
|
| `A` | Add column with name and value/expression |
|
|
211
288
|
| `-` (minus) | Delete current column |
|
|
212
289
|
| `x` | Delete current row |
|
|
290
|
+
| `X` | Delete current row and all rows below |
|
|
291
|
+
| `Ctrl+X` | Delete current row and all rows above |
|
|
213
292
|
| `d` | Duplicate current column (appends '_copy' suffix) |
|
|
214
293
|
| `D` | Duplicate current row |
|
|
215
294
|
| `h` | Hide current column |
|
|
216
|
-
| `H` | Show all hidden columns |
|
|
295
|
+
| `H` | Show all hidden rows/columns |
|
|
217
296
|
|
|
218
297
|
#### Searching & Filtering
|
|
219
298
|
|
|
@@ -234,12 +313,19 @@ When multiple files are opened:
|
|
|
234
313
|
| `v` | View only rows by selected rows and/or matches or cursor value |
|
|
235
314
|
| `V` | View only rows by expression |
|
|
236
315
|
|
|
316
|
+
#### SQL Interface
|
|
317
|
+
|
|
318
|
+
| Key | Action |
|
|
319
|
+
|-----|--------|
|
|
320
|
+
| `l` | Simple SQL interface (select columns & WHERE clause) |
|
|
321
|
+
| `L` | Advanced SQL interface (full SQL queries) |
|
|
322
|
+
|
|
237
323
|
#### Find & Replace
|
|
238
324
|
|
|
239
325
|
| Key | Action |
|
|
240
326
|
|-----|--------|
|
|
241
|
-
|
|
|
242
|
-
|
|
|
327
|
+
| `;` | Find across all columns with cursor value |
|
|
328
|
+
| `:` | Find across all columns with expression |
|
|
243
329
|
| `r` | Find and replace in current column (interactive or replace all) |
|
|
244
330
|
| `R` | Find and replace across all columns (interactive or replace all) |
|
|
245
331
|
|
|
@@ -280,7 +366,8 @@ When multiple files are opened:
|
|
|
280
366
|
| `Ctrl+R` | Copy row to clipboard (tab-separated) |
|
|
281
367
|
| `Ctrl+S` | Save current tab to file |
|
|
282
368
|
| `u` | Undo last action |
|
|
283
|
-
| `U` |
|
|
369
|
+
| `U` | Redo last undone action |
|
|
370
|
+
| `Ctrl+U` | Reset to initial state |
|
|
284
371
|
|
|
285
372
|
## Features in Detail
|
|
286
373
|
|
|
@@ -314,8 +401,8 @@ The application provides multiple search modes for different use cases:
|
|
|
314
401
|
**Find Operations** - Find by value/expression:
|
|
315
402
|
- **`/` - Column Find**: Find cursor value within current column
|
|
316
403
|
- **`?` - Column Expression Find**: Open dialog to search current column with expression
|
|
317
|
-
-
|
|
318
|
-
-
|
|
404
|
+
- **`;` - Global Find**: Find cursor value across all columns
|
|
405
|
+
- **`:` - Global Expression Find**: Open dialog to search all columns with expression
|
|
319
406
|
|
|
320
407
|
**Selection & Filtering**:
|
|
321
408
|
- **`'` - Toggle Row Selection**: Select/deselect current row (marks it for filtering)
|
|
@@ -509,7 +596,7 @@ Press `F` to see how many times each value appears in the current column. The mo
|
|
|
509
596
|
**In the Frequency Table**:
|
|
510
597
|
- Press `[` and `]` to sort by any column (value, count, or percentage)
|
|
511
598
|
- Press `v` to **filter** the main table to show only rows with the selected value
|
|
512
|
-
- Press `"` to **
|
|
599
|
+
- Press `"` to **exclude** all rows except those containing the selected value
|
|
513
600
|
- Press `q` or `Escape` to close the frequency table
|
|
514
601
|
|
|
515
602
|
This is useful for:
|
|
@@ -557,9 +644,25 @@ This is useful for:
|
|
|
557
644
|
- Delete all selected rows (if any) at once
|
|
558
645
|
- Or delete single row at cursor
|
|
559
646
|
|
|
647
|
+
**Delete Row and Below** (`X`):
|
|
648
|
+
- Deletes the current row and all rows below it
|
|
649
|
+
- Useful for removing trailing data or the end of a dataset
|
|
650
|
+
|
|
651
|
+
**Delete Row and Above** (`Ctrl+X`):
|
|
652
|
+
- Deletes the current row and all rows above it
|
|
653
|
+
- Useful for removing leading rows or the beginning of a dataset
|
|
654
|
+
|
|
560
655
|
**Delete Column** (`-`):
|
|
561
656
|
- Removes the entire column from view and dataframe
|
|
562
657
|
|
|
658
|
+
**Delete Column and After** (`_`):
|
|
659
|
+
- Deletes the current column and all columns to the right
|
|
660
|
+
- Useful for removing trailing columns or the end of a dataset
|
|
661
|
+
|
|
662
|
+
**Delete Column and Before** (`Ctrl+-`):
|
|
663
|
+
- Deletes the current column and all columns to the left
|
|
664
|
+
- Useful for removing leading columns or the beginning of a dataset
|
|
665
|
+
|
|
563
666
|
### 9. Hide & Show Columns
|
|
564
667
|
|
|
565
668
|
**Hide Column** (`h`):
|
|
@@ -567,9 +670,8 @@ This is useful for:
|
|
|
567
670
|
- Column data is preserved in the dataframe
|
|
568
671
|
- Hidden columns are included in saves
|
|
569
672
|
|
|
570
|
-
**Show Hidden Columns** (`H`):
|
|
571
|
-
- Restores all previously hidden columns to the display
|
|
572
|
-
- Returns table to full column view
|
|
673
|
+
**Show Hidden Rows/Columns** (`H`):
|
|
674
|
+
- Restores all previously hidden rows/columns to the display
|
|
573
675
|
|
|
574
676
|
This is useful for:
|
|
575
677
|
- Focusing on specific columns without deleting data
|
|
@@ -631,14 +733,23 @@ Press `Ctrl+S` to save:
|
|
|
631
733
|
- Choose filename in modal dialog
|
|
632
734
|
- Confirm if file already exists
|
|
633
735
|
|
|
634
|
-
### 15. Undo/Redo
|
|
736
|
+
### 15. Undo/Redo/Reset
|
|
635
737
|
|
|
636
|
-
|
|
738
|
+
**Undo** (`u`):
|
|
637
739
|
- Reverts last action with full state restoration
|
|
638
740
|
- Works for edits, deletions, sorts, searches, etc.
|
|
639
741
|
- Shows description of reverted action
|
|
640
742
|
|
|
641
|
-
|
|
743
|
+
**Redo** (`U`):
|
|
744
|
+
- Reapplies the last undone action
|
|
745
|
+
- Restores the state before the undo was performed
|
|
746
|
+
- Useful for redoing actions you've undone by mistake
|
|
747
|
+
- Useful for alternating between two different states
|
|
748
|
+
|
|
749
|
+
**Reset** (`Ctrl+U`):
|
|
750
|
+
- Reverts all changes and returns to original data state when file was first loaded
|
|
751
|
+
- Clears all edits, deletions, selections, filters, and sorts
|
|
752
|
+
- Useful for starting fresh without reloading the file
|
|
642
753
|
|
|
643
754
|
### 16. Column Type Conversion
|
|
644
755
|
|
|
@@ -671,7 +782,40 @@ Press `@` to make URLs in the current column clickable:
|
|
|
671
782
|
- **Scans** all cells in the current column for URLs starting with `http://` or `https://`
|
|
672
783
|
- **Applies** link styling to make them clickable and dataframe remains unchanged
|
|
673
784
|
|
|
674
|
-
### 19.
|
|
785
|
+
### 19. SQL Interface
|
|
786
|
+
|
|
787
|
+
The SQL interface provides two modes for querying your dataframe:
|
|
788
|
+
|
|
789
|
+
#### Simple SQL Interface (`l`)
|
|
790
|
+
Select specific columns and apply WHERE conditions without writing full SQL:
|
|
791
|
+
- Choose which columns to include in results
|
|
792
|
+
- Specify WHERE clause for filtering
|
|
793
|
+
- Ideal for quick filtering and column selection
|
|
794
|
+
|
|
795
|
+
#### Advanced SQL Interface (`L`)
|
|
796
|
+
Execute complete SQL queries for advanced data manipulation:
|
|
797
|
+
- Write full SQL queries with standard [SQL syntax](https://docs.pola.rs/api/python/stable/reference/sql/index.html)
|
|
798
|
+
- Support for JOINs, GROUP BY, aggregations, and more
|
|
799
|
+
- Access to all SQL capabilities for complex transformations
|
|
800
|
+
- Always use `self` as the table name
|
|
801
|
+
|
|
802
|
+
**Examples:**
|
|
803
|
+
```sql
|
|
804
|
+
-- Filter and select specific rows and/or columns
|
|
805
|
+
SELECT name, age FROM self WHERE age > 30
|
|
806
|
+
|
|
807
|
+
-- Aggregate with GROUP BY
|
|
808
|
+
SELECT department, COUNT(*) as count, AVG(salary) as avg_salary
|
|
809
|
+
FROM self
|
|
810
|
+
GROUP BY department
|
|
811
|
+
|
|
812
|
+
-- Complex filtering with multiple conditions
|
|
813
|
+
SELECT *
|
|
814
|
+
FROM self
|
|
815
|
+
WHERE (age > 25 AND salary > 50000) OR department = 'Management'
|
|
816
|
+
```
|
|
817
|
+
|
|
818
|
+
### 20. Clipboard Operations
|
|
675
819
|
|
|
676
820
|
Copies value to system clipboard with `pbcopy` on macOS and `xclip` on Linux
|
|
677
821
|
|
|
@@ -686,32 +830,47 @@ Press `Ctrl+C` to copy:
|
|
|
686
830
|
|
|
687
831
|
```bash
|
|
688
832
|
# View Pokemon dataset
|
|
689
|
-
|
|
833
|
+
dv pokemon.csv
|
|
834
|
+
|
|
835
|
+
# Chain with other command and specify input file format
|
|
836
|
+
cut -d',' -f1,2,3 pokemon.csv | dv -f csv
|
|
837
|
+
|
|
838
|
+
# Work with gzipped files
|
|
839
|
+
dv large_dataset.csv.gz
|
|
840
|
+
|
|
841
|
+
# CSV file without header row
|
|
842
|
+
dv -H raw_data.csv
|
|
843
|
+
|
|
844
|
+
# Skip type inference for faster loading
|
|
845
|
+
dv -I huge_file.csv
|
|
846
|
+
|
|
847
|
+
# Skip first 5 lines (comments, metadata)
|
|
848
|
+
dv -L 5 data_with_metadata.csv
|
|
690
849
|
|
|
691
|
-
#
|
|
692
|
-
|
|
850
|
+
# Skip 1 row after header (units row)
|
|
851
|
+
dv -K 1 data_with_units.csv
|
|
693
852
|
|
|
694
|
-
#
|
|
695
|
-
|
|
853
|
+
# Complex CSV with comments and units row
|
|
854
|
+
dv -L 3 -K 1 -I messy_scientific_data.csv
|
|
696
855
|
|
|
697
|
-
#
|
|
698
|
-
|
|
856
|
+
# Combine all options: skip lines, skip after header, no header, no inference, gzipped
|
|
857
|
+
dv -L 2 -K 1 -H -I complex_data.csv.gz
|
|
699
858
|
|
|
700
|
-
#
|
|
701
|
-
|
|
859
|
+
# Process compressed data from stdin with line skipping
|
|
860
|
+
zcat compressed_data.csv.gz | dv -f csv -L 2
|
|
702
861
|
```
|
|
703
862
|
|
|
704
863
|
### Multi-File/Tab Examples
|
|
705
864
|
|
|
706
865
|
```bash
|
|
707
866
|
# Open multiple sheets as tabs in a single Excel
|
|
708
|
-
|
|
867
|
+
dv sales.xlsx
|
|
709
868
|
|
|
710
|
-
# Open multiple files as tabs
|
|
711
|
-
|
|
869
|
+
# Open multiple files as tabs (including gzipped)
|
|
870
|
+
dv pokemon.csv titanic.csv large_data.csv.gz
|
|
712
871
|
|
|
713
872
|
# Start with one file, then open others using Ctrl+O
|
|
714
|
-
|
|
873
|
+
dv initial_data.csv
|
|
715
874
|
```
|
|
716
875
|
|
|
717
876
|
## Dependencies
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
dataframe_textual/__init__.py,sha256=IFPb8RMUgghw0eRomehkkC684Iny_gs1VkiZMQ5ZpFk,813
|
|
2
|
+
dataframe_textual/__main__.py,sha256=pNTqyzFO2xg_HDwNCu5MRLWEZdOB8_lzG62Za0ObyhE,2922
|
|
3
|
+
dataframe_textual/common.py,sha256=SAW06ArDY6VW2SjwlSBCTVEGsh66to3Hz5XH5ADAqew,24204
|
|
4
|
+
dataframe_textual/data_frame_help_panel.py,sha256=iEKaur-aH1N_oqHu-vMwEEjfkjQiThK24UO5izsOiW0,3416
|
|
5
|
+
dataframe_textual/data_frame_table.py,sha256=CQgRIyu6ek5nRCzME9N9eIIeVilK7gBBaYQEToJsV6g,120710
|
|
6
|
+
dataframe_textual/data_frame_viewer.py,sha256=S9RDcmom8sVksVo9X19zJWhyoE3mYp64vbDm5CvgLKM,12885
|
|
7
|
+
dataframe_textual/sql_screen.py,sha256=F-4C4AwjdyiXzLl6fheGrkVMfk-Yvz5EXaXPFfZq5xs,6165
|
|
8
|
+
dataframe_textual/table_screen.py,sha256=d9YBwzZ1Hh7d7PbbnpUxUTFrQ2AtL2wxv2gPrwkdxGg,18136
|
|
9
|
+
dataframe_textual/yes_no_screen.py,sha256=M39oBRrHbGAy476siNjNRJ8CqkkAlsJQtdJLnRM71nI,23228
|
|
10
|
+
dataframe_textual-1.4.0.dist-info/METADATA,sha256=Em_9725XE792LVualpaWr-a1s66UhNQ7FIQrMknqUEg,30745
|
|
11
|
+
dataframe_textual-1.4.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
12
|
+
dataframe_textual-1.4.0.dist-info/entry_points.txt,sha256=R_GoooOxcq6ab4RaHiVoZ4zrZJ-phMcGmlL2rwqncW8,107
|
|
13
|
+
dataframe_textual-1.4.0.dist-info/licenses/LICENSE,sha256=AVTg0gk1X-LHI-nnHlAMDQetrwuDZK4eypgSMDO46Yc,1069
|
|
14
|
+
dataframe_textual-1.4.0.dist-info/RECORD,,
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
dataframe_textual/__init__.py,sha256=uzB3bjlbm8JbsjxEgwqvPcYERktm3F9d9Op_6cWJ1sk,853
|
|
2
|
-
dataframe_textual/__main__.py,sha256=ANe7s2SKO53ksFg-0VrCT2GRCG48wDSAZsLrWvoQwmQ,2082
|
|
3
|
-
dataframe_textual/common.py,sha256=XVTzv565MnxD8B7tXKJSprhV5oOwvW_rv0RzMA9icmk,10896
|
|
4
|
-
dataframe_textual/data_frame_help_panel.py,sha256=XgKGEPJr2hnDWpZ5mavLRcBSPa9cvrXdzVUGFQavXm4,3353
|
|
5
|
-
dataframe_textual/data_frame_table.py,sha256=NzxtsOpSj6s-ToP5PBKlCHcSK3Fj5Q1eucUnQfTWLzQ,102638
|
|
6
|
-
dataframe_textual/data_frame_viewer.py,sha256=9vUBdIgSoOf4fdDtI4sAPY6cF1tFdsXwpWatyDsuXh0,17196
|
|
7
|
-
dataframe_textual/table_screen.py,sha256=qcfaSaDlM9Jb6793boyXt8HbHqM21-6O6eWwYn9z9l4,17624
|
|
8
|
-
dataframe_textual/yes_no_screen.py,sha256=vyUKMBbbwgt5At1U430eLg3WbJvqUNoz2GpvdnMd7q0,22921
|
|
9
|
-
dataframe_textual-1.0.0.dist-info/METADATA,sha256=SoeKzKEYNlKM2eKh_xzzlMegW83SDqkrXv_UouPQDsI,25753
|
|
10
|
-
dataframe_textual-1.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
11
|
-
dataframe_textual-1.0.0.dist-info/entry_points.txt,sha256=FkXDHVYYtGud6F2Jm2X9OMFAuFrSflNfgcNP5c2469M,70
|
|
12
|
-
dataframe_textual-1.0.0.dist-info/licenses/LICENSE,sha256=AVTg0gk1X-LHI-nnHlAMDQetrwuDZK4eypgSMDO46Yc,1069
|
|
13
|
-
dataframe_textual-1.0.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|