dataframe-toolkit 0.15.0__tar.gz → 0.15.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.
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/PKG-INFO +1 -1
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/pyproject.toml +1 -1
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/pyproject.toml.orig +1 -1
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/merge_cmd.py +20 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/common/docformats.py +24 -8
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/README.md +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/__init__.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/cli.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/__init__.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/annotate_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/base.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/binx_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/chi_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/clean_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/cleannames_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/concat_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/corr_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/dataset_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/describe_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/eval_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/explode_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/fit_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/func_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/help.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/hist_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/implode_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/info_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/interp_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/line_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/melt_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/pivot_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/print_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/query_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/randvar_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/sample_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/scale_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/scat_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/segid_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/skill_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/split_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/stat_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/test_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/transpose_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/wstat_cmd.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/common/__init__.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/common/copula.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/common/evalfuncs.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/common/io.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/common/plot.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/common/seed.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/common/seq.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/common/stats.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/io.py +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/skills/dftk/SKILL.md +0 -0
- {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/skills/dftk/references/snakemake.md +0 -0
|
@@ -29,6 +29,7 @@ import uuid
|
|
|
29
29
|
import pandas as pd
|
|
30
30
|
|
|
31
31
|
from dftk.commands.base import BaseCommand
|
|
32
|
+
from dftk.common import docformats
|
|
32
33
|
from dftk.common.io import check_cols, io
|
|
33
34
|
|
|
34
35
|
logger = logging.getLogger(__name__)
|
|
@@ -113,6 +114,24 @@ def _add_cross_col(
|
|
|
113
114
|
args.drop = drop
|
|
114
115
|
|
|
115
116
|
|
|
117
|
+
def _carry_json_columns(
|
|
118
|
+
merged: pd.DataFrame,
|
|
119
|
+
left: pd.DataFrame,
|
|
120
|
+
right: pd.DataFrame,
|
|
121
|
+
suffixes: tuple[str, str],
|
|
122
|
+
) -> None:
|
|
123
|
+
"""Mark the JSON-text columns of both inputs in *merged* (see docformats)."""
|
|
124
|
+
names = []
|
|
125
|
+
for side, other, suffix in ((left, right, suffixes[0]), (right, left, suffixes[1])):
|
|
126
|
+
for col in docformats.json_columns(side):
|
|
127
|
+
name = col
|
|
128
|
+
if col in other.columns and f"{col}{suffix}" in merged.columns:
|
|
129
|
+
name = f"{col}{suffix}"
|
|
130
|
+
if name in merged.columns and name not in names:
|
|
131
|
+
names.append(name)
|
|
132
|
+
docformats.mark_json_columns(merged, names)
|
|
133
|
+
|
|
134
|
+
|
|
116
135
|
def _gap_sides(args: argparse.Namespace) -> tuple[bool, bool]:
|
|
117
136
|
"""Return (left, right): which side's columns can get missing values.
|
|
118
137
|
|
|
@@ -227,6 +246,7 @@ def _do_merge(
|
|
|
227
246
|
if "_merge" in df_merged.columns:
|
|
228
247
|
df_merged = df_merged.drop(columns=["_merge"])
|
|
229
248
|
|
|
249
|
+
_carry_json_columns(df_merged, df_left, df_right, suffixes)
|
|
230
250
|
return df_merged
|
|
231
251
|
|
|
232
252
|
|
|
@@ -66,28 +66,35 @@ def _is_nested(value) -> bool:
|
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
def _dumps(value) -> str:
|
|
69
|
-
|
|
69
|
+
text = json.dumps(value, default=_plain, ensure_ascii=False, separators=(",", ":"))
|
|
70
|
+
if "NaN" in text or "Infinity" in text:
|
|
71
|
+
# NaN and Infinity aren't JSON: write them as null
|
|
72
|
+
parsed = json.loads(text, parse_constant=lambda _: None)
|
|
73
|
+
text = json.dumps(parsed, ensure_ascii=False, separators=(",", ":"))
|
|
74
|
+
return text
|
|
70
75
|
|
|
71
76
|
|
|
72
77
|
def nested_as_text(df: pd.DataFrame) -> pd.DataFrame:
|
|
73
78
|
"""Return *df* with nested values and JSON-column text as one-line text."""
|
|
74
79
|
jcols = set(json_columns(df))
|
|
75
80
|
out = None
|
|
76
|
-
|
|
77
|
-
|
|
81
|
+
# By position: column names may repeat
|
|
82
|
+
for i, col in enumerate(df.columns):
|
|
83
|
+
series = df.iloc[:, i]
|
|
84
|
+
dtype = series.dtype
|
|
78
85
|
if not (
|
|
79
86
|
pd.api.types.is_object_dtype(dtype) or pd.api.types.is_string_dtype(dtype)
|
|
80
87
|
):
|
|
81
88
|
continue
|
|
82
89
|
if col in jcols:
|
|
83
|
-
new =
|
|
84
|
-
elif
|
|
85
|
-
new =
|
|
90
|
+
new = series.map(_json_text_cell)
|
|
91
|
+
elif series.map(_is_nested).any():
|
|
92
|
+
new = series.map(lambda v: _dumps(v) if _is_nested(v) else v)
|
|
86
93
|
else:
|
|
87
94
|
continue
|
|
88
95
|
if out is None:
|
|
89
96
|
out = df.copy()
|
|
90
|
-
out
|
|
97
|
+
out.isetitem(i, new)
|
|
91
98
|
return df if out is None else out
|
|
92
99
|
|
|
93
100
|
|
|
@@ -131,6 +138,12 @@ def write_json(df: pd.DataFrame, dest, lines: bool, digits: int | None) -> None:
|
|
|
131
138
|
|
|
132
139
|
A missing value is written as null; the key is kept.
|
|
133
140
|
"""
|
|
141
|
+
repeated = df.columns[df.columns.duplicated()].unique().tolist()
|
|
142
|
+
if repeated:
|
|
143
|
+
raise ValueError(
|
|
144
|
+
f"JSON output needs unique column names; repeated: {repeated} "
|
|
145
|
+
"(rename one with --move OLD:NEW)"
|
|
146
|
+
)
|
|
134
147
|
jcols = set(json_columns(df))
|
|
135
148
|
cols = list(df.columns)
|
|
136
149
|
records = (
|
|
@@ -173,7 +186,7 @@ def _table(df: pd.DataFrame, float_format: str | None, escape):
|
|
|
173
186
|
[escape(_cell_text(v, float_format)) for v in row]
|
|
174
187
|
for row in df.itertuples(index=False, name=None)
|
|
175
188
|
]
|
|
176
|
-
numeric = [_is_numeric(df[
|
|
189
|
+
numeric = [_is_numeric(df.iloc[:, i]) for i in range(df.shape[1])]
|
|
177
190
|
return header, rows, numeric
|
|
178
191
|
|
|
179
192
|
|
|
@@ -206,6 +219,9 @@ _LATEX_SPECIAL = {
|
|
|
206
219
|
"_": r"\_",
|
|
207
220
|
"{": r"\{",
|
|
208
221
|
"}": r"\}",
|
|
222
|
+
# A row starting with [ after \\ would be read as \\[length]
|
|
223
|
+
"[": "{[}",
|
|
224
|
+
"]": "{]}",
|
|
209
225
|
"~": r"\textasciitilde{}",
|
|
210
226
|
"^": r"\textasciicircum{}",
|
|
211
227
|
# The default OT1 font prints these as an em dash and as inverted ! and ?
|
|
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
|
|
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
|
{dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/skills/dftk/references/snakemake.md
RENAMED
|
File without changes
|