absfuyu 5.11.0__py3-none-any.whl → 5.12.1__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.
Potentially problematic release.
This version of absfuyu might be problematic. Click here for more details.
- absfuyu/__init__.py +1 -1
- absfuyu/__main__.py +2 -2
- absfuyu/cli/__init__.py +2 -2
- absfuyu/cli/color.py +2 -2
- absfuyu/cli/config_group.py +2 -2
- absfuyu/cli/do_group.py +2 -2
- absfuyu/cli/game_group.py +2 -2
- absfuyu/cli/tool_group.py +2 -2
- absfuyu/config/__init__.py +2 -2
- absfuyu/core/__init__.py +2 -2
- absfuyu/core/baseclass.py +2 -2
- absfuyu/core/baseclass2.py +2 -2
- absfuyu/core/decorator.py +2 -2
- absfuyu/core/docstring.py +2 -2
- absfuyu/core/dummy_cli.py +3 -3
- absfuyu/core/dummy_func.py +2 -2
- absfuyu/dxt/__init__.py +2 -2
- absfuyu/dxt/dictext.py +186 -6
- absfuyu/dxt/dxt_support.py +2 -2
- absfuyu/dxt/intext.py +2 -2
- absfuyu/dxt/listext.py +320 -7
- absfuyu/dxt/strext.py +2 -2
- absfuyu/extra/__init__.py +2 -2
- absfuyu/extra/beautiful.py +2 -2
- absfuyu/extra/da/__init__.py +2 -2
- absfuyu/extra/da/dadf.py +73 -3
- absfuyu/extra/da/dadf_base.py +2 -2
- absfuyu/extra/da/df_func.py +2 -2
- absfuyu/extra/da/mplt.py +2 -2
- absfuyu/extra/data_analysis.py +2 -2
- absfuyu/extra/pdf.py +2 -2
- absfuyu/extra/rclone.py +2 -2
- absfuyu/extra/xml.py +2 -2
- absfuyu/fun/__init__.py +2 -2
- absfuyu/fun/rubik.py +2 -2
- absfuyu/fun/tarot.py +2 -2
- absfuyu/game/__init__.py +2 -2
- absfuyu/game/game_stat.py +2 -2
- absfuyu/game/schulte.py +2 -2
- absfuyu/game/sudoku.py +2 -2
- absfuyu/game/tictactoe.py +2 -2
- absfuyu/game/wordle.py +2 -2
- absfuyu/general/__init__.py +2 -2
- absfuyu/general/content.py +2 -2
- absfuyu/general/human.py +2 -2
- absfuyu/general/shape.py +2 -2
- absfuyu/general/tax.py +22 -2
- absfuyu/logger.py +2 -2
- absfuyu/pkg_data/__init__.py +2 -2
- absfuyu/pkg_data/deprecated.py +2 -2
- absfuyu/pkg_data/logo.py +2 -2
- absfuyu/sort.py +2 -2
- absfuyu/tools/__init__.py +2 -2
- absfuyu/tools/checksum.py +2 -2
- absfuyu/tools/converter.py +2 -2
- absfuyu/tools/generator.py +2 -2
- absfuyu/tools/inspector.py +2 -2
- absfuyu/tools/keygen.py +2 -2
- absfuyu/tools/obfuscator.py +2 -2
- absfuyu/tools/passwordlib.py +2 -2
- absfuyu/tools/shutdownizer.py +2 -2
- absfuyu/tools/sw.py +2 -2
- absfuyu/tools/web.py +2 -2
- absfuyu/typings.py +5 -2
- absfuyu/util/__init__.py +2 -2
- absfuyu/util/api.py +2 -2
- absfuyu/util/cli.py +118 -0
- absfuyu/util/gui.py +2 -2
- absfuyu/util/json_method.py +2 -2
- absfuyu/util/lunar.py +2 -2
- absfuyu/util/path.py +2 -2
- absfuyu/util/performance.py +2 -2
- absfuyu/util/shorten_number.py +2 -2
- absfuyu/util/text_table.py +2 -2
- absfuyu/util/zipped.py +2 -2
- absfuyu/version.py +2 -2
- {absfuyu-5.11.0.dist-info → absfuyu-5.12.1.dist-info}/METADATA +1 -1
- absfuyu-5.12.1.dist-info/RECORD +86 -0
- absfuyu-5.11.0.dist-info/RECORD +0 -85
- {absfuyu-5.11.0.dist-info → absfuyu-5.12.1.dist-info}/WHEEL +0 -0
- {absfuyu-5.11.0.dist-info → absfuyu-5.12.1.dist-info}/entry_points.txt +0 -0
- {absfuyu-5.11.0.dist-info → absfuyu-5.12.1.dist-info}/licenses/LICENSE +0 -0
absfuyu/dxt/listext.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Data Extension
|
|
|
3
3
|
-----------------------
|
|
4
4
|
list extension
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.12.0
|
|
7
|
+
Date updated: 17/10/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module Package
|
|
@@ -20,13 +20,16 @@ from collections import Counter
|
|
|
20
20
|
from collections.abc import Callable, Iterable
|
|
21
21
|
from heapq import heapreplace
|
|
22
22
|
from itertools import accumulate, chain, count, groupby, zip_longest
|
|
23
|
-
from typing import Any, Literal, Self, cast, overload
|
|
23
|
+
from typing import Any, Literal, Self, TypeVar, cast, overload
|
|
24
24
|
|
|
25
25
|
from absfuyu.core.baseclass import GetClassMembersMixin
|
|
26
26
|
from absfuyu.core.docstring import deprecated, versionadded, versionchanged
|
|
27
|
-
from absfuyu.typings import T as _T
|
|
28
27
|
from absfuyu.util import set_min_max
|
|
29
28
|
|
|
29
|
+
# Type
|
|
30
|
+
# ---------------------------------------------------------------------------
|
|
31
|
+
T = TypeVar("T")
|
|
32
|
+
R = TypeVar("R") # Return type - Can be anything
|
|
30
33
|
|
|
31
34
|
# Class
|
|
32
35
|
# ---------------------------------------------------------------------------
|
|
@@ -377,7 +380,7 @@ class ListExt(GetClassMembersMixin, list):
|
|
|
377
380
|
return self.__class__(zip(nums, self))
|
|
378
381
|
|
|
379
382
|
@versionadded("5.3.0") # no test case yet
|
|
380
|
-
def transpose(self, fillvalue:
|
|
383
|
+
def transpose(self, fillvalue: Any | None = None, /) -> Self:
|
|
381
384
|
"""
|
|
382
385
|
Transpose a list of iterable.
|
|
383
386
|
|
|
@@ -743,7 +746,7 @@ class ListExt(GetClassMembersMixin, list):
|
|
|
743
746
|
return self.slice_points(slice_points)
|
|
744
747
|
|
|
745
748
|
@versionadded("5.3.0") # no test case yet
|
|
746
|
-
def to_column(self, ncols: int, fillvalue:
|
|
749
|
+
def to_column(self, ncols: int, fillvalue: Any | None = None) -> Self:
|
|
747
750
|
"""
|
|
748
751
|
Smart convert 1 dimension list to 2 dimension list,
|
|
749
752
|
in which, number of columns = ``ncols``.
|
|
@@ -753,7 +756,7 @@ class ListExt(GetClassMembersMixin, list):
|
|
|
753
756
|
ncols : int
|
|
754
757
|
Number of columns
|
|
755
758
|
|
|
756
|
-
fillvalue :
|
|
759
|
+
fillvalue : Any | None, optional
|
|
757
760
|
Fill value, by default ``None``
|
|
758
761
|
|
|
759
762
|
Returns
|
|
@@ -871,3 +874,313 @@ class ListExt(GetClassMembersMixin, list):
|
|
|
871
874
|
mod_chunk = self.split_chunk(column_count).apply(mod_item)
|
|
872
875
|
|
|
873
876
|
return mod_chunk
|
|
877
|
+
|
|
878
|
+
|
|
879
|
+
class ListExt2(GetClassMembersMixin, list[T]):
|
|
880
|
+
"""
|
|
881
|
+
``list`` extension (with generic - W.I.P)
|
|
882
|
+
|
|
883
|
+
>>> # For a list of new methods
|
|
884
|
+
>>> ListExt2.show_all_methods()
|
|
885
|
+
"""
|
|
886
|
+
|
|
887
|
+
# Info
|
|
888
|
+
def head(self, number_of_items: int = 5, /) -> list[T]:
|
|
889
|
+
"""
|
|
890
|
+
Show first ``number_of_items`` items in ``ListExt``
|
|
891
|
+
|
|
892
|
+
Parameters
|
|
893
|
+
----------
|
|
894
|
+
number_of_items : int
|
|
895
|
+
| Number of items to shows at once
|
|
896
|
+
| (Default: ``5``)
|
|
897
|
+
|
|
898
|
+
Returns
|
|
899
|
+
-------
|
|
900
|
+
list
|
|
901
|
+
Filtered list
|
|
902
|
+
|
|
903
|
+
|
|
904
|
+
Example:
|
|
905
|
+
--------
|
|
906
|
+
>>> ListExt(range(10)).head(2)
|
|
907
|
+
[0, 1]
|
|
908
|
+
"""
|
|
909
|
+
number_of_items = int(set_min_max(number_of_items, min_value=0, max_value=len(self)))
|
|
910
|
+
return self[:number_of_items]
|
|
911
|
+
|
|
912
|
+
def tail(self, number_of_items: int = 5, /) -> list[T]:
|
|
913
|
+
"""
|
|
914
|
+
Show last ``number_of_items`` items in ``ListExt``
|
|
915
|
+
|
|
916
|
+
Parameters
|
|
917
|
+
----------
|
|
918
|
+
number_of_items : int
|
|
919
|
+
| Number of items to shows at once
|
|
920
|
+
| (Default: ``5``)
|
|
921
|
+
|
|
922
|
+
Returns
|
|
923
|
+
-------
|
|
924
|
+
list
|
|
925
|
+
Filtered list
|
|
926
|
+
|
|
927
|
+
|
|
928
|
+
Example:
|
|
929
|
+
--------
|
|
930
|
+
>>> ListExt(range(10)).tail(2)
|
|
931
|
+
[8, 9]
|
|
932
|
+
"""
|
|
933
|
+
number_of_items = int(set_min_max(number_of_items, min_value=0, max_value=len(self)))
|
|
934
|
+
return self[::-1][:number_of_items][::-1]
|
|
935
|
+
|
|
936
|
+
# Misc
|
|
937
|
+
def apply(self, func: Callable[[T], R]) -> "ListExt2[R]":
|
|
938
|
+
"""
|
|
939
|
+
Apply function to each entry
|
|
940
|
+
|
|
941
|
+
Parameters
|
|
942
|
+
----------
|
|
943
|
+
func : Callable[[Any], Any]
|
|
944
|
+
Callable function
|
|
945
|
+
|
|
946
|
+
Returns
|
|
947
|
+
-------
|
|
948
|
+
Self
|
|
949
|
+
ListExt
|
|
950
|
+
|
|
951
|
+
|
|
952
|
+
Example:
|
|
953
|
+
--------
|
|
954
|
+
>>> test = ListExt([1, 2, 3])
|
|
955
|
+
>>> test.apply(str)
|
|
956
|
+
['1', '2', '3']
|
|
957
|
+
"""
|
|
958
|
+
# return self.__class__(map(func, self))
|
|
959
|
+
return self.__class__(func(x) for x in self) # type: ignore
|
|
960
|
+
|
|
961
|
+
@versionchanged("5.2.0", reason="New ``recursive`` parameter")
|
|
962
|
+
def flatten(self, recursive: bool = False) -> "ListExt2":
|
|
963
|
+
"""
|
|
964
|
+
Flatten the list
|
|
965
|
+
|
|
966
|
+
Parameters
|
|
967
|
+
----------
|
|
968
|
+
recursive : bool
|
|
969
|
+
Recursively flatten the list, by default ``False``
|
|
970
|
+
|
|
971
|
+
Returns
|
|
972
|
+
-------
|
|
973
|
+
Self
|
|
974
|
+
Flattened list
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
Example:
|
|
978
|
+
--------
|
|
979
|
+
>>> test = ListExt([["test"], ["test", "test"], ["test"]])
|
|
980
|
+
>>> test.flatten()
|
|
981
|
+
['test', 'test', 'test', 'test']
|
|
982
|
+
"""
|
|
983
|
+
|
|
984
|
+
def instance_checking(item):
|
|
985
|
+
if isinstance(item, str):
|
|
986
|
+
return [item]
|
|
987
|
+
if isinstance(item, Iterable):
|
|
988
|
+
return item
|
|
989
|
+
return [item]
|
|
990
|
+
|
|
991
|
+
# Flatten
|
|
992
|
+
list_of_list = (instance_checking(x) for x in self)
|
|
993
|
+
flattened = self.__class__(chain(*list_of_list))
|
|
994
|
+
|
|
995
|
+
# Recursive
|
|
996
|
+
if recursive:
|
|
997
|
+
|
|
998
|
+
def _condition(item) -> bool:
|
|
999
|
+
if isinstance(item, str):
|
|
1000
|
+
return False
|
|
1001
|
+
return isinstance(item, Iterable)
|
|
1002
|
+
|
|
1003
|
+
while any(flattened.apply(_condition)):
|
|
1004
|
+
flattened = flattened.flatten()
|
|
1005
|
+
|
|
1006
|
+
# Return
|
|
1007
|
+
return flattened
|
|
1008
|
+
|
|
1009
|
+
@versionadded("5.2.0")
|
|
1010
|
+
def join(self, sep: str = " ", /) -> str:
|
|
1011
|
+
"""
|
|
1012
|
+
Join every element in list to str (``str.join()`` wrapper).
|
|
1013
|
+
|
|
1014
|
+
Parameters
|
|
1015
|
+
----------
|
|
1016
|
+
sep : str, optional
|
|
1017
|
+
Separator between each element, by default ``" "``
|
|
1018
|
+
|
|
1019
|
+
Returns
|
|
1020
|
+
-------
|
|
1021
|
+
str
|
|
1022
|
+
Joined list
|
|
1023
|
+
|
|
1024
|
+
|
|
1025
|
+
Example:
|
|
1026
|
+
--------
|
|
1027
|
+
>>> ListExt(["a", "b", "c"]).join()
|
|
1028
|
+
a b c
|
|
1029
|
+
|
|
1030
|
+
>>> # Also work with non-str type
|
|
1031
|
+
>>> ListExt([1, 2, 3]).join()
|
|
1032
|
+
1 2 3
|
|
1033
|
+
"""
|
|
1034
|
+
try:
|
|
1035
|
+
return sep.join(self) # type: ignore
|
|
1036
|
+
except TypeError:
|
|
1037
|
+
return sep.join(self.apply(str))
|
|
1038
|
+
|
|
1039
|
+
# Random
|
|
1040
|
+
def pick_one(self) -> T:
|
|
1041
|
+
"""
|
|
1042
|
+
Pick one random items from ``list``
|
|
1043
|
+
|
|
1044
|
+
Returns
|
|
1045
|
+
-------
|
|
1046
|
+
Any
|
|
1047
|
+
Random value
|
|
1048
|
+
|
|
1049
|
+
|
|
1050
|
+
Example:
|
|
1051
|
+
--------
|
|
1052
|
+
>>> test = ListExt(["foo", "bar"])
|
|
1053
|
+
>>> test.pick_one()
|
|
1054
|
+
'bar'
|
|
1055
|
+
"""
|
|
1056
|
+
if len(self) != 0:
|
|
1057
|
+
out = random.choice(self)
|
|
1058
|
+
# logger.debug(out)
|
|
1059
|
+
return out
|
|
1060
|
+
else:
|
|
1061
|
+
# logger.debug("List empty!")
|
|
1062
|
+
raise IndexError("List empty!")
|
|
1063
|
+
|
|
1064
|
+
def get_random(self, number_of_items: int = 5, /) -> list[T]:
|
|
1065
|
+
"""
|
|
1066
|
+
Get ``number_of_items`` random items in ``ListExt``
|
|
1067
|
+
|
|
1068
|
+
Parameters
|
|
1069
|
+
----------
|
|
1070
|
+
number_of_items : int
|
|
1071
|
+
Number random of items, by default ``5``
|
|
1072
|
+
|
|
1073
|
+
Returns
|
|
1074
|
+
-------
|
|
1075
|
+
list
|
|
1076
|
+
Filtered list
|
|
1077
|
+
"""
|
|
1078
|
+
return [self.pick_one() for _ in range(number_of_items)]
|
|
1079
|
+
|
|
1080
|
+
@versionadded("5.10.0")
|
|
1081
|
+
def shuffle(self) -> Self:
|
|
1082
|
+
"""
|
|
1083
|
+
Shuffle the list itself
|
|
1084
|
+
|
|
1085
|
+
Returns
|
|
1086
|
+
-------
|
|
1087
|
+
Self
|
|
1088
|
+
Shuffled list
|
|
1089
|
+
"""
|
|
1090
|
+
random.shuffle(self)
|
|
1091
|
+
return self
|
|
1092
|
+
|
|
1093
|
+
# Len
|
|
1094
|
+
@versionchanged("5.2.0", reason="Handle more type")
|
|
1095
|
+
def len_items(self) -> "ListExt2[int]":
|
|
1096
|
+
"""
|
|
1097
|
+
``len()`` for every item in ``self``
|
|
1098
|
+
|
|
1099
|
+
Returns
|
|
1100
|
+
-------
|
|
1101
|
+
Self
|
|
1102
|
+
List of ``len()``'ed value
|
|
1103
|
+
|
|
1104
|
+
|
|
1105
|
+
Example:
|
|
1106
|
+
--------
|
|
1107
|
+
>>> test = ListExt(["foo", "bar", "pizza"])
|
|
1108
|
+
>>> test.len_items()
|
|
1109
|
+
[3, 3, 5]
|
|
1110
|
+
"""
|
|
1111
|
+
|
|
1112
|
+
def _len(item: Any) -> int:
|
|
1113
|
+
try:
|
|
1114
|
+
return len(item)
|
|
1115
|
+
except TypeError:
|
|
1116
|
+
return len(str(item))
|
|
1117
|
+
|
|
1118
|
+
return self.__class__([_len(x) for x in self]) # type: ignore
|
|
1119
|
+
|
|
1120
|
+
@versionchanged("5.2.0", reason="New ``recursive`` parameter")
|
|
1121
|
+
def mean_len(self, recursive: bool = False) -> float:
|
|
1122
|
+
"""
|
|
1123
|
+
Average length of every item. Returns zero if failed (empty list, ZeroDivisionError).
|
|
1124
|
+
|
|
1125
|
+
Parameters
|
|
1126
|
+
----------
|
|
1127
|
+
recursive : bool
|
|
1128
|
+
Recursively find the average length of items in nested lists, by default ``False``
|
|
1129
|
+
|
|
1130
|
+
Returns
|
|
1131
|
+
-------
|
|
1132
|
+
float
|
|
1133
|
+
Average length
|
|
1134
|
+
|
|
1135
|
+
|
|
1136
|
+
Example:
|
|
1137
|
+
--------
|
|
1138
|
+
>>> test = ListExt(["foo", "bar", "pizza"])
|
|
1139
|
+
>>> test.mean_len()
|
|
1140
|
+
3.6666666666666665
|
|
1141
|
+
"""
|
|
1142
|
+
|
|
1143
|
+
if recursive:
|
|
1144
|
+
dat = self.flatten(recursive=recursive)
|
|
1145
|
+
else:
|
|
1146
|
+
dat = self
|
|
1147
|
+
|
|
1148
|
+
try:
|
|
1149
|
+
return sum(dat.len_items()) / len(dat)
|
|
1150
|
+
except ZeroDivisionError:
|
|
1151
|
+
return 0.0
|
|
1152
|
+
|
|
1153
|
+
@versionadded("5.2.0")
|
|
1154
|
+
def max_item_len(self, recursive: bool = False) -> int:
|
|
1155
|
+
"""
|
|
1156
|
+
Find the maximum length of items in the list.
|
|
1157
|
+
|
|
1158
|
+
Parameters
|
|
1159
|
+
----------
|
|
1160
|
+
recursive : bool
|
|
1161
|
+
Recursively find the maximum length of items in nested lists, by default ``False``
|
|
1162
|
+
|
|
1163
|
+
Returns
|
|
1164
|
+
-------
|
|
1165
|
+
int
|
|
1166
|
+
Maximum length of items
|
|
1167
|
+
|
|
1168
|
+
|
|
1169
|
+
Example:
|
|
1170
|
+
--------
|
|
1171
|
+
>>> test = ListExt(["test", "longer_test"])
|
|
1172
|
+
>>> test.max_item_len()
|
|
1173
|
+
11
|
|
1174
|
+
|
|
1175
|
+
>>> test = ListExt([["short"], ["longer_test"]])
|
|
1176
|
+
>>> test.max_item_len(recursive=True)
|
|
1177
|
+
11
|
|
1178
|
+
"""
|
|
1179
|
+
if recursive:
|
|
1180
|
+
return cast(int, max(self.flatten(recursive=True).len_items()))
|
|
1181
|
+
return cast(int, max(self.len_items()))
|
|
1182
|
+
|
|
1183
|
+
|
|
1184
|
+
if __name__ == "__main__":
|
|
1185
|
+
test = ListExt2([1, 2, 3, 4, 5])
|
|
1186
|
+
a = test.pick_one()
|
absfuyu/dxt/strext.py
CHANGED
absfuyu/extra/__init__.py
CHANGED
absfuyu/extra/beautiful.py
CHANGED
absfuyu/extra/da/__init__.py
CHANGED
absfuyu/extra/da/dadf.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Data Analysis
|
|
|
3
3
|
----------------------
|
|
4
4
|
Data Analyst DataFrame
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.12.0
|
|
7
|
+
Date updated: 17/10/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module level
|
|
@@ -28,7 +28,7 @@ import random
|
|
|
28
28
|
import string
|
|
29
29
|
from collections.abc import Callable, Sequence
|
|
30
30
|
from datetime import datetime, timedelta
|
|
31
|
-
from typing import Any, Literal, Self
|
|
31
|
+
from typing import Any, Literal, Self, cast
|
|
32
32
|
|
|
33
33
|
import numpy as np
|
|
34
34
|
import pandas as pd
|
|
@@ -40,6 +40,11 @@ try:
|
|
|
40
40
|
except ImportError:
|
|
41
41
|
from absfuyu.core.decorator import dummy_decorator as override
|
|
42
42
|
|
|
43
|
+
try:
|
|
44
|
+
from unidecode import unidecode # type: ignore
|
|
45
|
+
except ImportError:
|
|
46
|
+
from absfuyu.core.dummy_func import dummy_function as unidecode
|
|
47
|
+
|
|
43
48
|
from absfuyu.core.baseclass import GetClassMembersMixin
|
|
44
49
|
from absfuyu.core.docstring import deprecated, versionadded, versionchanged
|
|
45
50
|
from absfuyu.extra.da.dadf_base import CityData
|
|
@@ -62,6 +67,8 @@ class DataAnalystDataFrameColumnMethodMixin(DFBase):
|
|
|
62
67
|
- Drop rightmost column
|
|
63
68
|
- Add blank column
|
|
64
69
|
- Split str column
|
|
70
|
+
- Get column name unidecoded
|
|
71
|
+
- Get column unidecoded
|
|
65
72
|
"""
|
|
66
73
|
|
|
67
74
|
def rearrange_rightmost_column(
|
|
@@ -257,6 +264,69 @@ class DataAnalystDataFrameColumnMethodMixin(DFBase):
|
|
|
257
264
|
self[new_col_names] = splited_data
|
|
258
265
|
return self
|
|
259
266
|
|
|
267
|
+
@versionadded("5.12.0") # No test cases
|
|
268
|
+
def get_column_name_unidecoded(self, col_name: str, /, *, mode: Literal["start", "end", "in"] = "start") -> str:
|
|
269
|
+
"""
|
|
270
|
+
Get column name from lowercase unidecode'd version name
|
|
271
|
+
|
|
272
|
+
Parameters
|
|
273
|
+
----------
|
|
274
|
+
col_name : str
|
|
275
|
+
Column name to find
|
|
276
|
+
|
|
277
|
+
mode : Literal["start", "end", "in"], optional
|
|
278
|
+
Which mode to find, by default "start"
|
|
279
|
+
- "start": str.startswith()
|
|
280
|
+
- "end": str.endswith()
|
|
281
|
+
- "in": if x in y
|
|
282
|
+
|
|
283
|
+
Returns
|
|
284
|
+
-------
|
|
285
|
+
str
|
|
286
|
+
Column name
|
|
287
|
+
|
|
288
|
+
Raises
|
|
289
|
+
------
|
|
290
|
+
ValueError
|
|
291
|
+
Column not found
|
|
292
|
+
"""
|
|
293
|
+
for x in self.columns.to_list():
|
|
294
|
+
col_name_mod = cast(str, unidecode(x.strip().lower()))
|
|
295
|
+
if mode == "start":
|
|
296
|
+
if col_name_mod.startswith(col_name):
|
|
297
|
+
return x
|
|
298
|
+
elif mode == "end":
|
|
299
|
+
if col_name_mod.endswith(col_name):
|
|
300
|
+
return x
|
|
301
|
+
elif mode == "in":
|
|
302
|
+
if col_name_mod in col_name:
|
|
303
|
+
return x
|
|
304
|
+
|
|
305
|
+
raise ValueError(f"Column not found: {col_name}")
|
|
306
|
+
|
|
307
|
+
@versionadded("5.12.0") # No test cases
|
|
308
|
+
def get_column_unidecoded(self, col_name: str, /, *, mode: Literal["start", "end", "in"] = "start") -> pd.Series:
|
|
309
|
+
"""
|
|
310
|
+
Get column from lowercase unidecode'd version column name
|
|
311
|
+
|
|
312
|
+
Parameters
|
|
313
|
+
----------
|
|
314
|
+
col_name : str
|
|
315
|
+
Column name to find
|
|
316
|
+
|
|
317
|
+
mode : Literal["start", "end", "in"], optional
|
|
318
|
+
Which mode to find, by default "start"
|
|
319
|
+
- "start": str.startswith()
|
|
320
|
+
- "end": str.endswith()
|
|
321
|
+
- "in": if x in y
|
|
322
|
+
|
|
323
|
+
Returns
|
|
324
|
+
-------
|
|
325
|
+
Series
|
|
326
|
+
Column data
|
|
327
|
+
"""
|
|
328
|
+
return self[self.get_column_name_unidecoded(col_name, mode=mode)]
|
|
329
|
+
|
|
260
330
|
|
|
261
331
|
# Row method
|
|
262
332
|
# ---------------------------------------------------------------------------
|
absfuyu/extra/da/dadf_base.py
CHANGED
absfuyu/extra/da/df_func.py
CHANGED
absfuyu/extra/da/mplt.py
CHANGED
absfuyu/extra/data_analysis.py
CHANGED
absfuyu/extra/pdf.py
CHANGED
absfuyu/extra/rclone.py
CHANGED
absfuyu/extra/xml.py
CHANGED
absfuyu/fun/__init__.py
CHANGED
absfuyu/fun/rubik.py
CHANGED
absfuyu/fun/tarot.py
CHANGED
absfuyu/game/__init__.py
CHANGED
absfuyu/game/game_stat.py
CHANGED
absfuyu/game/schulte.py
CHANGED