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.
Files changed (55) hide show
  1. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/PKG-INFO +1 -1
  2. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/pyproject.toml +1 -1
  3. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/pyproject.toml.orig +1 -1
  4. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/merge_cmd.py +20 -0
  5. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/common/docformats.py +24 -8
  6. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/README.md +0 -0
  7. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/__init__.py +0 -0
  8. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/cli.py +0 -0
  9. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/__init__.py +0 -0
  10. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/annotate_cmd.py +0 -0
  11. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/base.py +0 -0
  12. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/binx_cmd.py +0 -0
  13. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/chi_cmd.py +0 -0
  14. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/clean_cmd.py +0 -0
  15. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/cleannames_cmd.py +0 -0
  16. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/concat_cmd.py +0 -0
  17. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/corr_cmd.py +0 -0
  18. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/dataset_cmd.py +0 -0
  19. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/describe_cmd.py +0 -0
  20. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/eval_cmd.py +0 -0
  21. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/explode_cmd.py +0 -0
  22. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/fit_cmd.py +0 -0
  23. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/func_cmd.py +0 -0
  24. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/help.py +0 -0
  25. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/hist_cmd.py +0 -0
  26. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/implode_cmd.py +0 -0
  27. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/info_cmd.py +0 -0
  28. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/interp_cmd.py +0 -0
  29. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/line_cmd.py +0 -0
  30. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/melt_cmd.py +0 -0
  31. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/pivot_cmd.py +0 -0
  32. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/print_cmd.py +0 -0
  33. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/query_cmd.py +0 -0
  34. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/randvar_cmd.py +0 -0
  35. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/sample_cmd.py +0 -0
  36. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/scale_cmd.py +0 -0
  37. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/scat_cmd.py +0 -0
  38. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/segid_cmd.py +0 -0
  39. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/skill_cmd.py +0 -0
  40. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/split_cmd.py +0 -0
  41. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/stat_cmd.py +0 -0
  42. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/test_cmd.py +0 -0
  43. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/transpose_cmd.py +0 -0
  44. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/commands/wstat_cmd.py +0 -0
  45. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/common/__init__.py +0 -0
  46. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/common/copula.py +0 -0
  47. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/common/evalfuncs.py +0 -0
  48. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/common/io.py +0 -0
  49. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/common/plot.py +0 -0
  50. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/common/seed.py +0 -0
  51. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/common/seq.py +0 -0
  52. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/common/stats.py +0 -0
  53. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/io.py +0 -0
  54. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/skills/dftk/SKILL.md +0 -0
  55. {dataframe_toolkit-0.15.0 → dataframe_toolkit-0.15.1}/src/dftk/skills/dftk/references/snakemake.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dataframe-toolkit
3
- Version: 0.15.0
3
+ Version: 0.15.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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "dataframe-toolkit"
3
- version = "0.15.0"
3
+ version = "0.15.1"
4
4
  description = "A command-line toolkit for DataFrame analysis and manipulation"
5
5
  readme = "README.md"
6
6
  keywords = [
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "dataframe-toolkit"
3
- version = "0.15.0"
3
+ version = "0.15.1"
4
4
  description = "A command-line toolkit for DataFrame analysis and manipulation"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -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
- return json.dumps(value, default=_plain, ensure_ascii=False, separators=(",", ":"))
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
- for col in df.columns:
77
- dtype = df[col].dtype
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 = df[col].map(_json_text_cell)
84
- elif df[col].map(_is_nested).any():
85
- new = df[col].map(lambda v: _dumps(v) if _is_nested(v) else v)
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[col] = new
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[c]) for c in df.columns]
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 ?