dukit 0.2.5__tar.gz → 0.2.7__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.
- {dukit-0.2.5 → dukit-0.2.7}/PKG-INFO +3 -3
- {dukit-0.2.5 → dukit-0.2.7}/README.md +2 -2
- {dukit-0.2.5 → dukit-0.2.7}/pyproject.toml +1 -1
- {dukit-0.2.5 → dukit-0.2.7}/src/dukit/__init__.py +26 -10
- {dukit-0.2.5 → dukit-0.2.7}/src/dukit/_test_utils.py +4 -49
- {dukit-0.2.5 → dukit-0.2.7}/src/dukit/diffing.py +125 -28
- {dukit-0.2.5 → dukit-0.2.7}/src/dukit/excel.py +20 -1
- {dukit-0.2.5 → dukit-0.2.7}/src/dukit/interfaces.py +140 -66
- {dukit-0.2.5 → dukit-0.2.7}/src/dukit/pandas.py +638 -136
- {dukit-0.2.5 → dukit-0.2.7}/src/dukit/qlang/symbols.py +182 -4
- {dukit-0.2.5 → dukit-0.2.7}/src/dukit/typing.py +9 -4
- {dukit-0.2.5 → dukit-0.2.7}/src/dukit/os.py +0 -0
- {dukit-0.2.5 → dukit-0.2.7}/src/dukit/py.typed +0 -0
- {dukit-0.2.5 → dukit-0.2.7}/src/dukit/qlang/__init__.py +0 -0
- {dukit-0.2.5 → dukit-0.2.7}/src/dukit/qlang/engine.py +0 -0
- {dukit-0.2.5 → dukit-0.2.7}/src/dukit/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dukit
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.7
|
|
4
4
|
Summary: dukit - data utilities kit for exploring, modifying and visualizing small but messy data using pandas
|
|
5
5
|
Keywords: pandas,query,utility,data,diff
|
|
6
6
|
Author: MartinVoelkl94
|
|
@@ -89,8 +89,8 @@ these functions offer various ways to deal with non-unique keys/ids.
|
|
|
89
89
|
primarily used when merging 2 dfs with a one-to-many relationship.
|
|
90
90
|
|
|
91
91
|
available functions:
|
|
92
|
-
- df.dk.
|
|
93
|
-
- df.dk.
|
|
92
|
+
- df.dk.stack()
|
|
93
|
+
- df.dk.unstack()
|
|
94
94
|
- df.dk.embed()
|
|
95
95
|
- df.dk.collapse()
|
|
96
96
|
<br>
|
|
@@ -72,8 +72,8 @@ these functions offer various ways to deal with non-unique keys/ids.
|
|
|
72
72
|
primarily used when merging 2 dfs with a one-to-many relationship.
|
|
73
73
|
|
|
74
74
|
available functions:
|
|
75
|
-
- df.dk.
|
|
76
|
-
- df.dk.
|
|
75
|
+
- df.dk.stack()
|
|
76
|
+
- df.dk.unstack()
|
|
77
77
|
- df.dk.embed()
|
|
78
78
|
- df.dk.collapse()
|
|
79
79
|
<br>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "dukit"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.7"
|
|
4
4
|
description = "dukit - data utilities kit for exploring, modifying and visualizing small but messy data using pandas"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [{ name = "MartinVoelkl94", email = "martinv16248@gmail.com" }]
|
|
@@ -24,16 +24,24 @@ from .excel import (
|
|
|
24
24
|
save,
|
|
25
25
|
)
|
|
26
26
|
from .pandas import (
|
|
27
|
-
|
|
27
|
+
compose,
|
|
28
|
+
decompose,
|
|
29
|
+
stack,
|
|
30
|
+
unstack,
|
|
31
|
+
transpose,
|
|
28
32
|
date_delta,
|
|
29
33
|
date_table,
|
|
30
34
|
deduplicate,
|
|
31
|
-
embed,
|
|
32
|
-
flatten,
|
|
33
35
|
get_df,
|
|
34
|
-
|
|
36
|
+
get_df_patients,
|
|
37
|
+
get_df_medications,
|
|
38
|
+
get_df_old,
|
|
39
|
+
get_df_new,
|
|
40
|
+
split_col,
|
|
41
|
+
embed,
|
|
42
|
+
collapse,
|
|
35
43
|
stagger,
|
|
36
|
-
|
|
44
|
+
flatten,
|
|
37
45
|
)
|
|
38
46
|
from .os import (
|
|
39
47
|
cd,
|
|
@@ -85,16 +93,24 @@ __all__ = (
|
|
|
85
93
|
'format',
|
|
86
94
|
'save',
|
|
87
95
|
|
|
88
|
-
'
|
|
96
|
+
'compose',
|
|
97
|
+
'decompose',
|
|
98
|
+
'stack',
|
|
99
|
+
'unstack',
|
|
100
|
+
'transpose',
|
|
89
101
|
'date_delta',
|
|
90
102
|
'date_table',
|
|
91
103
|
'deduplicate',
|
|
92
|
-
'embed',
|
|
93
|
-
'flatten',
|
|
94
104
|
'get_df',
|
|
95
|
-
'
|
|
105
|
+
'get_df_patients',
|
|
106
|
+
'get_df_medications',
|
|
107
|
+
'get_df_old',
|
|
108
|
+
'get_df_new',
|
|
109
|
+
'split_col',
|
|
110
|
+
'embed',
|
|
111
|
+
'collapse',
|
|
96
112
|
'stagger',
|
|
97
|
-
'
|
|
113
|
+
'flatten',
|
|
98
114
|
|
|
99
115
|
'cd',
|
|
100
116
|
'cp',
|
|
@@ -33,51 +33,6 @@ def _setup_xlsx(df_old, df_new, tmpdir):
|
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
def _get_dfs():
|
|
37
|
-
|
|
38
|
-
df_old = pd.DataFrame(
|
|
39
|
-
columns=['a', 'b', 'c'],
|
|
40
|
-
index=['x', 'y', 'z', ],
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
df_old.insert(0, 'uid', df_old.index)
|
|
44
|
-
|
|
45
|
-
df_old.loc['x', 'a'] = 1
|
|
46
|
-
df_old.loc['x', 'b'] = 1
|
|
47
|
-
df_old.loc['x', 'c'] = 1
|
|
48
|
-
|
|
49
|
-
df_old.loc['y', 'a'] = 2
|
|
50
|
-
df_old.loc['y', 'b'] = 2
|
|
51
|
-
df_old.loc['y', 'c'] = 2
|
|
52
|
-
|
|
53
|
-
df_old.loc['z', 'a'] = 3
|
|
54
|
-
df_old.loc['z', 'b'] = None
|
|
55
|
-
df_old.loc['z', 'c'] = 3
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
df_new = pd.DataFrame(
|
|
59
|
-
columns=['d', 'b', 'a'],
|
|
60
|
-
index=['y', 'x2', 'z', ],
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
df_new.insert(0, 'uid', df_new.index)
|
|
64
|
-
|
|
65
|
-
df_new.loc['y', 'd'] = 2
|
|
66
|
-
df_new.loc['y', 'b'] = 2
|
|
67
|
-
df_new.loc['y', 'a'] = 0
|
|
68
|
-
|
|
69
|
-
df_new.loc['x2', 'd'] = 1
|
|
70
|
-
df_new.loc['x2', 'b'] = 1
|
|
71
|
-
df_new.loc['x2', 'a'] = 1
|
|
72
|
-
|
|
73
|
-
df_new.loc['z', 'd'] = 3
|
|
74
|
-
df_new.loc['z', 'b'] = 3
|
|
75
|
-
df_new.loc['z', 'a'] = pd.NA
|
|
76
|
-
|
|
77
|
-
return df_old, df_new
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
36
|
def _get_expected_new():
|
|
82
37
|
|
|
83
38
|
uid = pd.Series(
|
|
@@ -86,7 +41,7 @@ def _get_expected_new():
|
|
|
86
41
|
name='uid',
|
|
87
42
|
)
|
|
88
43
|
expected = pd.DataFrame(
|
|
89
|
-
columns=['
|
|
44
|
+
columns=['diff', 'uid', 'd', 'b', 'a'],
|
|
90
45
|
index=uid,
|
|
91
46
|
)
|
|
92
47
|
|
|
@@ -121,7 +76,7 @@ def _get_expected_newplus():
|
|
|
121
76
|
name='uid',
|
|
122
77
|
)
|
|
123
78
|
expected = pd.DataFrame(
|
|
124
|
-
columns=['
|
|
79
|
+
columns=['diff', 'uid', 'd', 'b', 'b *old', 'a', 'a *old'],
|
|
125
80
|
index=uid,
|
|
126
81
|
)
|
|
127
82
|
|
|
@@ -165,7 +120,7 @@ def _get_expected_old():
|
|
|
165
120
|
name='uid',
|
|
166
121
|
)
|
|
167
122
|
expected = pd.DataFrame(
|
|
168
|
-
columns=['
|
|
123
|
+
columns=['diff', 'uid', 'a', 'b', 'c'],
|
|
169
124
|
index=uid,
|
|
170
125
|
)
|
|
171
126
|
|
|
@@ -200,7 +155,7 @@ def _get_expected_mix():
|
|
|
200
155
|
name='uid',
|
|
201
156
|
)
|
|
202
157
|
expected = pd.DataFrame(
|
|
203
|
-
columns=['
|
|
158
|
+
columns=['diff', 'uid', 'd', 'b', 'a', 'c'],
|
|
204
159
|
index=uid,
|
|
205
160
|
)
|
|
206
161
|
|
|
@@ -27,6 +27,7 @@ def diff(
|
|
|
27
27
|
remove_cols: list | str = None,
|
|
28
28
|
remove_cols_by_suffix='',
|
|
29
29
|
retain_cols: list | str = None,
|
|
30
|
+
retain_rows: list | str = None,
|
|
30
31
|
ignore_cols: list | str = None,
|
|
31
32
|
remove_sheets: list | str = None,
|
|
32
33
|
name='data',
|
|
@@ -50,11 +51,11 @@ def diff(
|
|
|
50
51
|
controls the values included in each result.
|
|
51
52
|
- 'mix': show rows and cols from old and new df.
|
|
52
53
|
additions and deletions are highlighted.
|
|
53
|
-
- 'old': show only rows and cols from the old df.
|
|
54
|
-
deletions are highlighted.
|
|
55
54
|
- 'new': show only rows and cols from the new df.
|
|
56
55
|
additions are highlighted.
|
|
57
56
|
- 'new+': also preserve changed old values in parallel metadata cols.
|
|
57
|
+
- 'old': show only rows and cols from the old df.
|
|
58
|
+
deletions are highlighted.
|
|
58
59
|
rename_cols : dict, optional
|
|
59
60
|
mapping of original col names to names used during comparison.
|
|
60
61
|
remove_cols : list or str, optional
|
|
@@ -62,7 +63,9 @@ def diff(
|
|
|
62
63
|
remove_cols_by_suffix : str, default ''
|
|
63
64
|
remove cols whose names end with this suffix.
|
|
64
65
|
retain_cols : list or str, optional
|
|
65
|
-
keep
|
|
66
|
+
keep these cols from the old df.
|
|
67
|
+
retain_rows : list or str, optional
|
|
68
|
+
keep these rows from the old df.
|
|
66
69
|
ignore_cols : list or str, optional
|
|
67
70
|
cols excluded from comparison.
|
|
68
71
|
remove_sheets : list or str, optional
|
|
@@ -111,6 +114,7 @@ def diff(
|
|
|
111
114
|
remove_cols=remove_cols,
|
|
112
115
|
remove_cols_by_suffix=remove_cols_by_suffix,
|
|
113
116
|
retain_cols=retain_cols,
|
|
117
|
+
retain_rows=retain_rows,
|
|
114
118
|
ignore_cols=ignore_cols,
|
|
115
119
|
remove_sheets=remove_sheets,
|
|
116
120
|
name=name,
|
|
@@ -132,6 +136,7 @@ def rediff(
|
|
|
132
136
|
remove_cols: list | str = 'diff',
|
|
133
137
|
remove_cols_by_suffix=' *old',
|
|
134
138
|
retain_cols: list | str = 'notes',
|
|
139
|
+
retain_rows: list | str = 'notes',
|
|
135
140
|
ignore_cols: list | str = None,
|
|
136
141
|
remove_sheets=['info', 'summary', 'details'],
|
|
137
142
|
name='data',
|
|
@@ -154,6 +159,7 @@ def rediff(
|
|
|
154
159
|
remove_cols=remove_cols,
|
|
155
160
|
remove_cols_by_suffix=remove_cols_by_suffix,
|
|
156
161
|
retain_cols=retain_cols,
|
|
162
|
+
retain_rows=retain_rows,
|
|
157
163
|
ignore_cols=ignore_cols,
|
|
158
164
|
remove_sheets=remove_sheets,
|
|
159
165
|
name=name,
|
|
@@ -182,6 +188,7 @@ class Diffs:
|
|
|
182
188
|
remove_cols: list | str = None,
|
|
183
189
|
remove_cols_by_suffix='',
|
|
184
190
|
retain_cols: list | str = None,
|
|
191
|
+
retain_rows: list | str = None,
|
|
185
192
|
ignore_cols: list | str = None,
|
|
186
193
|
remove_sheets: list | str = None,
|
|
187
194
|
name='data',
|
|
@@ -232,6 +239,7 @@ class Diffs:
|
|
|
232
239
|
remove_cols=remove_cols,
|
|
233
240
|
remove_cols_by_suffix=remove_cols_by_suffix,
|
|
234
241
|
retain_cols=retain_cols,
|
|
242
|
+
retain_rows=retain_rows,
|
|
235
243
|
ignore_cols=ignore_cols,
|
|
236
244
|
linebreak=linebreak,
|
|
237
245
|
suffix_old=suffix_old,
|
|
@@ -641,6 +649,7 @@ def _get_diffs(
|
|
|
641
649
|
remove_cols: list | str = None,
|
|
642
650
|
remove_cols_by_suffix='',
|
|
643
651
|
retain_cols: list | str = None,
|
|
652
|
+
retain_rows: list | str = None,
|
|
644
653
|
ignore_cols: list | str = None,
|
|
645
654
|
linebreak='<br>',
|
|
646
655
|
suffix_old=' *old',
|
|
@@ -660,6 +669,7 @@ def _get_diffs(
|
|
|
660
669
|
mode=mode,
|
|
661
670
|
rename_cols=rename_cols,
|
|
662
671
|
retain_cols=retain_cols,
|
|
672
|
+
retain_rows=retain_rows,
|
|
663
673
|
remove_cols=remove_cols,
|
|
664
674
|
remove_cols_by_suffix=remove_cols_by_suffix,
|
|
665
675
|
ignore_cols=ignore_cols,
|
|
@@ -677,6 +687,7 @@ def _get_diffs(
|
|
|
677
687
|
mode=mode,
|
|
678
688
|
rename_cols=rename_cols,
|
|
679
689
|
retain_cols=retain_cols,
|
|
690
|
+
retain_rows=retain_rows,
|
|
680
691
|
remove_cols=remove_cols,
|
|
681
692
|
remove_cols_by_suffix=remove_cols_by_suffix,
|
|
682
693
|
ignore_cols=ignore_cols,
|
|
@@ -694,6 +705,7 @@ def _get_diffs(
|
|
|
694
705
|
mode=mode,
|
|
695
706
|
rename_cols=rename_cols,
|
|
696
707
|
retain_cols=retain_cols,
|
|
708
|
+
retain_rows=retain_rows,
|
|
697
709
|
remove_cols=remove_cols,
|
|
698
710
|
remove_cols_by_suffix=remove_cols_by_suffix,
|
|
699
711
|
ignore_cols=ignore_cols,
|
|
@@ -719,6 +731,7 @@ def _get_single_diff(
|
|
|
719
731
|
remove_cols: list | str = None,
|
|
720
732
|
remove_cols_by_suffix='',
|
|
721
733
|
retain_cols: list | str = None,
|
|
734
|
+
retain_rows: list | str = None,
|
|
722
735
|
ignore_cols: list | str = None,
|
|
723
736
|
name='data',
|
|
724
737
|
linebreak='<br>',
|
|
@@ -752,6 +765,7 @@ def _get_single_diff(
|
|
|
752
765
|
|
|
753
766
|
d = _set_uid(d, uid)
|
|
754
767
|
d = _retain_cols(d, list_(retain_cols)) #depends on _set_uid()
|
|
768
|
+
d = _retain_rows(d, list_(retain_rows)) #depends on _set_uid()
|
|
755
769
|
d = _ignore_cols(d, list_(ignore_cols))
|
|
756
770
|
|
|
757
771
|
d = _create_working_values(d)
|
|
@@ -769,8 +783,10 @@ def _get_single_diff(
|
|
|
769
783
|
d = _populate_diff_col(d) #depends on _get_row_col_diffs() and _get_val_diffs()
|
|
770
784
|
|
|
771
785
|
d = _add_retained_cols(d)
|
|
772
|
-
d =
|
|
786
|
+
d = _add_retained_rows(d)
|
|
773
787
|
d = _add_uid_col(d)
|
|
788
|
+
d = _add_diff_col(d)
|
|
789
|
+
d = _reset_index(d)
|
|
774
790
|
d = _apply_style(d)
|
|
775
791
|
|
|
776
792
|
return d
|
|
@@ -822,7 +838,8 @@ class Diff:
|
|
|
822
838
|
self.vals_changed: pd.Series = pd.Series(dtype='int')
|
|
823
839
|
|
|
824
840
|
#helper attributes for internal use
|
|
825
|
-
self.
|
|
841
|
+
self._cols_retained: pd.DataFrame
|
|
842
|
+
self._rows_retained: pd.DataFrame
|
|
826
843
|
self._cols_ignore: list[str]
|
|
827
844
|
self._metadata_col_mapping: dict[str, str]
|
|
828
845
|
self._mask_added: pd.DataFrame
|
|
@@ -863,9 +880,10 @@ class Diff:
|
|
|
863
880
|
f'vals changed: {sum(self.vals_changed)}\n'
|
|
864
881
|
)
|
|
865
882
|
txt += (
|
|
866
|
-
'>>>d.
|
|
867
|
-
'>>>d.
|
|
868
|
-
'>>>d.
|
|
883
|
+
'>>>d.show()\n'
|
|
884
|
+
'>>>d.info()\n'
|
|
885
|
+
'>>>d.summary()\n'
|
|
886
|
+
'>>>d.details()\n'
|
|
869
887
|
)
|
|
870
888
|
txt += '----------------Diff object end----------------\n'
|
|
871
889
|
|
|
@@ -919,7 +937,8 @@ def _handle_edgecases(d: Diff) -> Diff:
|
|
|
919
937
|
d._values = values
|
|
920
938
|
d._style = style
|
|
921
939
|
|
|
922
|
-
d.
|
|
940
|
+
d._cols_retained = pd.DataFrame()
|
|
941
|
+
d._rows_retained = pd.DataFrame()
|
|
923
942
|
d._cols_ignore = []
|
|
924
943
|
d._metadata_col_mapping = {}
|
|
925
944
|
d._mask_added = pd.DataFrame(dtype='bool')
|
|
@@ -1117,17 +1136,41 @@ def _retain_cols(d: Diff, cols: list) -> Diff:
|
|
|
1117
1136
|
"""
|
|
1118
1137
|
|
|
1119
1138
|
if not cols:
|
|
1120
|
-
d.
|
|
1139
|
+
d._cols_retained = pd.DataFrame()
|
|
1121
1140
|
return d
|
|
1122
1141
|
|
|
1123
1142
|
cols_retain_old = d.old.columns.intersection(cols)
|
|
1124
1143
|
cols_retain_new = d.new.columns.intersection(cols)
|
|
1125
1144
|
|
|
1126
|
-
|
|
1145
|
+
cols_retained = d.old[cols_retain_old].copy()
|
|
1127
1146
|
|
|
1128
1147
|
d.old = d.old.drop(columns=cols_retain_old)
|
|
1129
1148
|
d.new = d.new.drop(columns=cols_retain_new)
|
|
1130
|
-
d.
|
|
1149
|
+
d._cols_retained = cols_retained
|
|
1150
|
+
|
|
1151
|
+
return d
|
|
1152
|
+
|
|
1153
|
+
|
|
1154
|
+
|
|
1155
|
+
def _retain_rows(d: Diff, rows: list) -> Diff:
|
|
1156
|
+
"""
|
|
1157
|
+
remove rows from both dfs before diffing,
|
|
1158
|
+
then readd the ones from the old df to
|
|
1159
|
+
the diff result later.
|
|
1160
|
+
"""
|
|
1161
|
+
|
|
1162
|
+
if not rows:
|
|
1163
|
+
d._rows_retained = pd.DataFrame()
|
|
1164
|
+
return d
|
|
1165
|
+
|
|
1166
|
+
rows_retain_old = d.old.index.intersection(rows)
|
|
1167
|
+
rows_retain_new = d.new.index.intersection(rows)
|
|
1168
|
+
|
|
1169
|
+
rows_retained = d.old.loc[rows_retain_old].copy()
|
|
1170
|
+
|
|
1171
|
+
d.old = d.old.drop(index=rows_retain_old)
|
|
1172
|
+
d.new = d.new.drop(index=rows_retain_new)
|
|
1173
|
+
d._rows_retained = rows_retained
|
|
1131
1174
|
|
|
1132
1175
|
return d
|
|
1133
1176
|
|
|
@@ -1158,7 +1201,7 @@ def _create_working_values(d: Diff) -> Diff:
|
|
|
1158
1201
|
if d.mode == 'mix':
|
|
1159
1202
|
rows_old_only = d.old.index.difference(d.new.index)
|
|
1160
1203
|
cols_old_only = d.old.columns.difference(d.new.columns)
|
|
1161
|
-
d._values = pd.concat([d.new, d.old.loc[:, cols_old_only]], axis=
|
|
1204
|
+
d._values = pd.concat([d.new, d.old.loc[:, cols_old_only]], axis='columns')
|
|
1162
1205
|
d._values.loc[rows_old_only, :] = d.old.loc[rows_old_only, :]
|
|
1163
1206
|
|
|
1164
1207
|
elif d.mode == 'old':
|
|
@@ -1266,11 +1309,11 @@ def _create_meta_cols(d: Diff) -> Diff:
|
|
|
1266
1309
|
|
|
1267
1310
|
values = pd.concat(
|
|
1268
1311
|
[values, df_meta],
|
|
1269
|
-
axis=
|
|
1312
|
+
axis='columns',
|
|
1270
1313
|
)
|
|
1271
1314
|
style = pd.concat(
|
|
1272
1315
|
[style, df_meta_style],
|
|
1273
|
-
axis=
|
|
1316
|
+
axis='columns',
|
|
1274
1317
|
)
|
|
1275
1318
|
|
|
1276
1319
|
d._metadata_col_mapping = col_mapping
|
|
@@ -1396,9 +1439,9 @@ def _populate_val_styles(d: Diff) -> Diff:
|
|
|
1396
1439
|
|
|
1397
1440
|
def _populate_diff_col(d: Diff) -> Diff:
|
|
1398
1441
|
|
|
1399
|
-
sum_added = d._mask_added.sum(axis=
|
|
1400
|
-
sum_removed = d._mask_removed.sum(axis=
|
|
1401
|
-
sum_changed = d._mask_changed.sum(axis=
|
|
1442
|
+
sum_added = d._mask_added.sum(axis='columns')
|
|
1443
|
+
sum_removed = d._mask_removed.sum(axis='columns')
|
|
1444
|
+
sum_changed = d._mask_changed.sum(axis='columns')
|
|
1402
1445
|
|
|
1403
1446
|
rows_added = sum_added[sum_added > 0].index
|
|
1404
1447
|
rows_removed = sum_removed[sum_removed > 0].index
|
|
@@ -1450,21 +1493,60 @@ def _populate_meta_cols(d: Diff) -> Diff:
|
|
|
1450
1493
|
|
|
1451
1494
|
def _add_retained_cols(d: Diff) -> Diff:
|
|
1452
1495
|
|
|
1453
|
-
if d.
|
|
1496
|
+
if d._cols_retained.empty:
|
|
1454
1497
|
return d
|
|
1455
1498
|
|
|
1456
|
-
idx_shared = d._values.index.intersection(d.
|
|
1457
|
-
df_retained = d.
|
|
1458
|
-
d._values = pd.
|
|
1499
|
+
idx_shared = d._values.index.intersection(d._cols_retained.index)
|
|
1500
|
+
df_retained = d._cols_retained.loc[idx_shared, :]
|
|
1501
|
+
d._values = pd.merge(
|
|
1502
|
+
df_retained,
|
|
1503
|
+
d._values,
|
|
1504
|
+
left_index=True,
|
|
1505
|
+
right_index=True,
|
|
1506
|
+
how='right',
|
|
1507
|
+
)
|
|
1459
1508
|
|
|
1509
|
+
df_style = pd.DataFrame(
|
|
1510
|
+
data='',
|
|
1511
|
+
index=df_retained.index,
|
|
1512
|
+
columns=df_retained.columns,
|
|
1513
|
+
)
|
|
1514
|
+
d._style = pd.merge(
|
|
1515
|
+
df_style,
|
|
1516
|
+
d._style,
|
|
1517
|
+
left_index=True,
|
|
1518
|
+
right_index=True,
|
|
1519
|
+
how='right',
|
|
1520
|
+
)
|
|
1460
1521
|
return d
|
|
1461
1522
|
|
|
1462
1523
|
|
|
1463
1524
|
|
|
1464
|
-
def
|
|
1465
|
-
|
|
1466
|
-
d.
|
|
1467
|
-
|
|
1525
|
+
def _add_retained_rows(d: Diff) -> Diff:
|
|
1526
|
+
|
|
1527
|
+
if d._rows_retained.empty:
|
|
1528
|
+
return d
|
|
1529
|
+
|
|
1530
|
+
cols_shared = d._values.columns.intersection(d._rows_retained.columns)
|
|
1531
|
+
df_retained = d._rows_retained.loc[:, cols_shared]
|
|
1532
|
+
cols_ordered = d._values.columns
|
|
1533
|
+
d._values = pd.concat([df_retained, d._values], axis='index')
|
|
1534
|
+
d._values = d._values[cols_ordered]
|
|
1535
|
+
|
|
1536
|
+
df_style = pd.DataFrame(
|
|
1537
|
+
data='',
|
|
1538
|
+
index=df_retained.index,
|
|
1539
|
+
columns=cols_shared,
|
|
1540
|
+
)
|
|
1541
|
+
d._style = pd.concat([df_style, d._style], axis='index')
|
|
1542
|
+
|
|
1543
|
+
blank_retained = pd.Series(
|
|
1544
|
+
'',
|
|
1545
|
+
index=df_retained.index,
|
|
1546
|
+
name=d._diff_col.name,
|
|
1547
|
+
)
|
|
1548
|
+
d._diff_col = pd.concat([blank_retained, d._diff_col], axis='index')
|
|
1549
|
+
|
|
1468
1550
|
return d
|
|
1469
1551
|
|
|
1470
1552
|
|
|
@@ -1477,7 +1559,21 @@ def _add_uid_col(d: Diff) -> Diff:
|
|
|
1477
1559
|
index=d._values.index,
|
|
1478
1560
|
name=colname_uid,
|
|
1479
1561
|
)
|
|
1480
|
-
d._values = pd.concat([uid_col, d._values], axis=
|
|
1562
|
+
d._values = pd.concat([uid_col, d._values], axis='columns')
|
|
1563
|
+
|
|
1564
|
+
return d
|
|
1565
|
+
|
|
1566
|
+
|
|
1567
|
+
|
|
1568
|
+
def _add_diff_col(d: Diff) -> Diff:
|
|
1569
|
+
colname = ensure_unique_string('diff', d._values.columns)
|
|
1570
|
+
d._diff_col.name = colname
|
|
1571
|
+
d._values = pd.concat([d._diff_col, d._values], axis='columns')
|
|
1572
|
+
return d
|
|
1573
|
+
|
|
1574
|
+
|
|
1575
|
+
|
|
1576
|
+
def _reset_index(d: Diff) -> Diff:
|
|
1481
1577
|
|
|
1482
1578
|
index_diff = d._values.index.difference(d._style.index)
|
|
1483
1579
|
if index_diff.empty:
|
|
@@ -1489,7 +1585,7 @@ def _add_uid_col(d: Diff) -> Diff:
|
|
|
1489
1585
|
'This should never happen. Please report this issue.'
|
|
1490
1586
|
f'Index difference: {index_diff}'
|
|
1491
1587
|
)
|
|
1492
|
-
log(msg, 'dk.diffing.
|
|
1588
|
+
log(msg, 'dk.diffing._reset_index', d.verbosity)
|
|
1493
1589
|
|
|
1494
1590
|
return d
|
|
1495
1591
|
|
|
@@ -1506,6 +1602,7 @@ def _apply_style(d: Diff) -> Diff:
|
|
|
1506
1602
|
)
|
|
1507
1603
|
log(msg, context, d.verbosity)
|
|
1508
1604
|
|
|
1605
|
+
d._style.fillna('', inplace=True)
|
|
1509
1606
|
d.result = (
|
|
1510
1607
|
d._values
|
|
1511
1608
|
.style
|
|
@@ -136,6 +136,14 @@ def save(
|
|
|
136
136
|
sheet_name='df',
|
|
137
137
|
index=False,
|
|
138
138
|
format_excel=True,
|
|
139
|
+
freeze_panes='B2',
|
|
140
|
+
hide_sheets=None,
|
|
141
|
+
hide_cols=None,
|
|
142
|
+
col_width_max=70,
|
|
143
|
+
col_width_padding=2,
|
|
144
|
+
align_vertical='top',
|
|
145
|
+
align_horizontal='left',
|
|
146
|
+
wrap_text=True,
|
|
139
147
|
**kwargs,
|
|
140
148
|
):
|
|
141
149
|
"""
|
|
@@ -184,4 +192,15 @@ def save(
|
|
|
184
192
|
)
|
|
185
193
|
|
|
186
194
|
if format_excel:
|
|
187
|
-
format(
|
|
195
|
+
format(
|
|
196
|
+
path,
|
|
197
|
+
sheet=sheet_name,
|
|
198
|
+
freeze_panes=freeze_panes,
|
|
199
|
+
hide_sheets=hide_sheets,
|
|
200
|
+
hide_cols=hide_cols,
|
|
201
|
+
col_width_max=col_width_max,
|
|
202
|
+
col_width_padding=col_width_padding,
|
|
203
|
+
align_vertical=align_vertical,
|
|
204
|
+
align_horizontal=align_horizontal,
|
|
205
|
+
wrap_text=wrap_text,
|
|
206
|
+
)
|