maxframe 2.0.0b2__cp311-cp311-win_amd64.whl → 2.2.0__cp311-cp311-win_amd64.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 maxframe might be problematic. Click here for more details.

Files changed (391) hide show
  1. maxframe/__init__.py +1 -0
  2. maxframe/_utils.cp311-win_amd64.pyd +0 -0
  3. maxframe/_utils.pyx +14 -1
  4. maxframe/codegen/core.py +6 -6
  5. maxframe/codegen/spe/core.py +1 -1
  6. maxframe/codegen/spe/dataframe/__init__.py +1 -0
  7. maxframe/codegen/spe/dataframe/accessors/base.py +18 -0
  8. maxframe/codegen/spe/dataframe/accessors/dict_.py +25 -130
  9. maxframe/codegen/spe/dataframe/accessors/list_.py +12 -48
  10. maxframe/codegen/spe/dataframe/accessors/struct_.py +28 -0
  11. maxframe/codegen/spe/dataframe/arithmetic.py +7 -2
  12. maxframe/codegen/spe/dataframe/groupby.py +88 -0
  13. maxframe/codegen/spe/dataframe/indexing.py +99 -4
  14. maxframe/codegen/spe/dataframe/merge.py +34 -1
  15. maxframe/codegen/spe/dataframe/misc.py +9 -33
  16. maxframe/codegen/spe/dataframe/reduction.py +14 -9
  17. maxframe/codegen/spe/dataframe/reshape.py +46 -0
  18. maxframe/codegen/spe/dataframe/sort.py +30 -17
  19. maxframe/codegen/spe/dataframe/tests/accessors/test_dict.py +9 -15
  20. maxframe/codegen/spe/dataframe/tests/accessors/test_list.py +4 -7
  21. maxframe/codegen/spe/dataframe/tests/accessors/test_struct.py +75 -0
  22. maxframe/codegen/spe/dataframe/tests/indexing/test_iloc.py +20 -1
  23. maxframe/codegen/spe/dataframe/tests/indexing/test_loc.py +35 -0
  24. maxframe/codegen/spe/dataframe/tests/misc/test_misc.py +0 -32
  25. maxframe/codegen/spe/dataframe/tests/test_groupby.py +81 -18
  26. maxframe/codegen/spe/dataframe/tests/test_merge.py +27 -1
  27. maxframe/codegen/spe/dataframe/tests/test_reshape.py +79 -0
  28. maxframe/codegen/spe/dataframe/tests/test_sort.py +20 -0
  29. maxframe/codegen/spe/learn/contrib/tests/test_xgboost.py +2 -1
  30. maxframe/codegen/spe/learn/metrics/__init__.py +1 -1
  31. maxframe/codegen/spe/learn/metrics/_ranking.py +76 -0
  32. maxframe/codegen/spe/learn/metrics/pairwise.py +51 -0
  33. maxframe/codegen/spe/learn/metrics/tests/test_pairwise.py +36 -0
  34. maxframe/codegen/spe/learn/metrics/tests/test_ranking.py +59 -0
  35. maxframe/codegen/spe/tensor/__init__.py +3 -0
  36. maxframe/codegen/spe/tensor/fft.py +74 -0
  37. maxframe/codegen/spe/tensor/linalg.py +29 -2
  38. maxframe/codegen/spe/tensor/misc.py +79 -25
  39. maxframe/codegen/spe/tensor/spatial.py +45 -0
  40. maxframe/codegen/spe/tensor/statistics.py +44 -0
  41. maxframe/codegen/spe/tensor/tests/test_fft.py +64 -0
  42. maxframe/codegen/spe/tensor/tests/test_linalg.py +15 -1
  43. maxframe/codegen/spe/tensor/tests/test_misc.py +52 -2
  44. maxframe/codegen/spe/tensor/tests/test_spatial.py +33 -0
  45. maxframe/codegen/spe/tensor/tests/test_statistics.py +15 -1
  46. maxframe/codegen/spe/tests/test_spe_codegen.py +6 -12
  47. maxframe/codegen/spe/utils.py +2 -0
  48. maxframe/config/config.py +70 -9
  49. maxframe/config/tests/test_validators.py +13 -1
  50. maxframe/config/validators.py +49 -0
  51. maxframe/conftest.py +44 -17
  52. maxframe/core/accessor.py +2 -2
  53. maxframe/core/entity/core.py +5 -0
  54. maxframe/core/entity/tileables.py +1 -1
  55. maxframe/core/graph/core.cp311-win_amd64.pyd +0 -0
  56. maxframe/core/graph/entity.py +1 -2
  57. maxframe/core/operator/base.py +9 -2
  58. maxframe/core/operator/core.py +10 -2
  59. maxframe/core/operator/utils.py +13 -0
  60. maxframe/dataframe/__init__.py +10 -3
  61. maxframe/dataframe/accessors/__init__.py +1 -1
  62. maxframe/dataframe/accessors/compat.py +45 -0
  63. maxframe/dataframe/accessors/datetime_/__init__.py +4 -1
  64. maxframe/dataframe/accessors/dict_/contains.py +7 -16
  65. maxframe/dataframe/accessors/dict_/core.py +48 -0
  66. maxframe/dataframe/accessors/dict_/getitem.py +17 -21
  67. maxframe/dataframe/accessors/dict_/length.py +7 -16
  68. maxframe/dataframe/accessors/dict_/remove.py +6 -18
  69. maxframe/dataframe/accessors/dict_/setitem.py +8 -18
  70. maxframe/dataframe/accessors/dict_/tests/test_dict_accessor.py +62 -22
  71. maxframe/dataframe/accessors/list_/__init__.py +2 -2
  72. maxframe/dataframe/accessors/list_/core.py +48 -0
  73. maxframe/dataframe/accessors/list_/getitem.py +12 -19
  74. maxframe/dataframe/accessors/list_/length.py +7 -16
  75. maxframe/dataframe/accessors/list_/tests/test_list_accessor.py +11 -9
  76. maxframe/dataframe/accessors/string_/__init__.py +4 -1
  77. maxframe/dataframe/accessors/struct_/__init__.py +37 -0
  78. maxframe/dataframe/accessors/struct_/accessor.py +39 -0
  79. maxframe/dataframe/accessors/struct_/core.py +43 -0
  80. maxframe/dataframe/accessors/struct_/dtypes.py +53 -0
  81. maxframe/dataframe/accessors/struct_/field.py +123 -0
  82. maxframe/dataframe/accessors/struct_/tests/__init__.py +13 -0
  83. maxframe/dataframe/accessors/struct_/tests/test_struct_accessor.py +91 -0
  84. maxframe/dataframe/arithmetic/__init__.py +14 -4
  85. maxframe/dataframe/arithmetic/between.py +106 -0
  86. maxframe/dataframe/arithmetic/dot.py +237 -0
  87. maxframe/dataframe/arithmetic/{around.py → round.py} +11 -7
  88. maxframe/dataframe/core.py +63 -118
  89. maxframe/dataframe/datasource/__init__.py +18 -0
  90. maxframe/dataframe/datasource/from_dict.py +124 -0
  91. maxframe/dataframe/datasource/from_index.py +1 -1
  92. maxframe/dataframe/datasource/from_records.py +77 -0
  93. maxframe/dataframe/datasource/from_tensor.py +109 -41
  94. maxframe/dataframe/datasource/read_csv.py +2 -3
  95. maxframe/dataframe/datasource/tests/test_datasource.py +37 -0
  96. maxframe/dataframe/datastore/__init__.py +5 -1
  97. maxframe/dataframe/datastore/to_csv.py +29 -41
  98. maxframe/dataframe/datastore/to_odps.py +30 -4
  99. maxframe/dataframe/extensions/__init__.py +20 -4
  100. maxframe/dataframe/extensions/apply_chunk.py +32 -6
  101. maxframe/dataframe/extensions/cartesian_chunk.py +153 -0
  102. maxframe/dataframe/extensions/collect_kv.py +126 -0
  103. maxframe/dataframe/extensions/extract_kv.py +177 -0
  104. maxframe/dataframe/extensions/map_reduce.py +263 -0
  105. maxframe/dataframe/extensions/rebalance.py +62 -0
  106. maxframe/dataframe/extensions/tests/test_apply_chunk.py +9 -2
  107. maxframe/dataframe/extensions/tests/test_extensions.py +54 -0
  108. maxframe/dataframe/extensions/tests/test_map_reduce.py +135 -0
  109. maxframe/dataframe/groupby/__init__.py +12 -1
  110. maxframe/dataframe/groupby/aggregation.py +78 -45
  111. maxframe/dataframe/groupby/apply.py +1 -1
  112. maxframe/dataframe/groupby/apply_chunk.py +18 -2
  113. maxframe/dataframe/groupby/core.py +96 -12
  114. maxframe/dataframe/groupby/cum.py +4 -25
  115. maxframe/dataframe/groupby/expanding.py +264 -0
  116. maxframe/dataframe/groupby/fill.py +1 -1
  117. maxframe/dataframe/groupby/getitem.py +12 -5
  118. maxframe/dataframe/groupby/head.py +11 -1
  119. maxframe/dataframe/groupby/rank.py +136 -0
  120. maxframe/dataframe/groupby/rolling.py +206 -0
  121. maxframe/dataframe/groupby/shift.py +114 -0
  122. maxframe/dataframe/groupby/tests/test_groupby.py +0 -5
  123. maxframe/dataframe/indexing/__init__.py +20 -1
  124. maxframe/dataframe/indexing/droplevel.py +195 -0
  125. maxframe/dataframe/indexing/filter.py +169 -0
  126. maxframe/dataframe/indexing/get_level_values.py +76 -0
  127. maxframe/dataframe/indexing/iat.py +45 -0
  128. maxframe/dataframe/indexing/iloc.py +152 -12
  129. maxframe/dataframe/indexing/insert.py +1 -1
  130. maxframe/dataframe/indexing/loc.py +287 -7
  131. maxframe/dataframe/indexing/reindex.py +14 -5
  132. maxframe/dataframe/indexing/rename.py +6 -0
  133. maxframe/dataframe/indexing/rename_axis.py +2 -2
  134. maxframe/dataframe/indexing/reorder_levels.py +143 -0
  135. maxframe/dataframe/indexing/reset_index.py +33 -6
  136. maxframe/dataframe/indexing/sample.py +8 -0
  137. maxframe/dataframe/indexing/setitem.py +3 -3
  138. maxframe/dataframe/indexing/swaplevel.py +185 -0
  139. maxframe/dataframe/indexing/take.py +99 -0
  140. maxframe/dataframe/indexing/truncate.py +140 -0
  141. maxframe/dataframe/indexing/where.py +0 -11
  142. maxframe/dataframe/indexing/xs.py +148 -0
  143. maxframe/dataframe/merge/__init__.py +12 -1
  144. maxframe/dataframe/merge/append.py +97 -98
  145. maxframe/dataframe/merge/combine_first.py +120 -0
  146. maxframe/dataframe/merge/compare.py +387 -0
  147. maxframe/dataframe/merge/concat.py +183 -0
  148. maxframe/dataframe/merge/update.py +271 -0
  149. maxframe/dataframe/misc/__init__.py +16 -10
  150. maxframe/dataframe/misc/_duplicate.py +10 -4
  151. maxframe/dataframe/misc/apply.py +1 -1
  152. maxframe/dataframe/misc/check_unique.py +51 -0
  153. maxframe/dataframe/misc/clip.py +145 -0
  154. maxframe/dataframe/misc/describe.py +175 -9
  155. maxframe/dataframe/misc/drop_duplicates.py +2 -2
  156. maxframe/dataframe/misc/duplicated.py +2 -2
  157. maxframe/dataframe/misc/get_dummies.py +5 -1
  158. maxframe/dataframe/misc/isin.py +2 -2
  159. maxframe/dataframe/misc/map.py +94 -0
  160. maxframe/dataframe/misc/tests/test_misc.py +13 -2
  161. maxframe/dataframe/misc/to_numeric.py +3 -0
  162. maxframe/dataframe/misc/transform.py +12 -5
  163. maxframe/dataframe/misc/transpose.py +13 -1
  164. maxframe/dataframe/misc/valid_index.py +115 -0
  165. maxframe/dataframe/misc/value_counts.py +38 -4
  166. maxframe/dataframe/missing/checkna.py +13 -6
  167. maxframe/dataframe/missing/dropna.py +5 -0
  168. maxframe/dataframe/missing/fillna.py +1 -1
  169. maxframe/dataframe/missing/replace.py +7 -4
  170. maxframe/dataframe/reduction/__init__.py +29 -15
  171. maxframe/dataframe/reduction/aggregation.py +38 -9
  172. maxframe/dataframe/reduction/all.py +2 -2
  173. maxframe/dataframe/reduction/any.py +2 -2
  174. maxframe/dataframe/reduction/argmax.py +100 -0
  175. maxframe/dataframe/reduction/argmin.py +100 -0
  176. maxframe/dataframe/reduction/core.py +65 -18
  177. maxframe/dataframe/reduction/count.py +13 -9
  178. maxframe/dataframe/reduction/cov.py +166 -0
  179. maxframe/dataframe/reduction/cummax.py +2 -2
  180. maxframe/dataframe/reduction/cummin.py +2 -2
  181. maxframe/dataframe/reduction/cumprod.py +2 -2
  182. maxframe/dataframe/reduction/cumsum.py +2 -2
  183. maxframe/dataframe/reduction/custom_reduction.py +2 -2
  184. maxframe/dataframe/reduction/idxmax.py +185 -0
  185. maxframe/dataframe/reduction/idxmin.py +185 -0
  186. maxframe/dataframe/reduction/kurtosis.py +37 -30
  187. maxframe/dataframe/reduction/max.py +2 -2
  188. maxframe/dataframe/reduction/mean.py +9 -7
  189. maxframe/dataframe/reduction/median.py +2 -2
  190. maxframe/dataframe/reduction/min.py +2 -2
  191. maxframe/dataframe/reduction/nunique.py +9 -8
  192. maxframe/dataframe/reduction/prod.py +18 -13
  193. maxframe/dataframe/reduction/reduction_size.py +2 -2
  194. maxframe/dataframe/reduction/sem.py +13 -9
  195. maxframe/dataframe/reduction/skew.py +31 -27
  196. maxframe/dataframe/reduction/str_concat.py +10 -7
  197. maxframe/dataframe/reduction/sum.py +18 -14
  198. maxframe/dataframe/reduction/unique.py +20 -3
  199. maxframe/dataframe/reduction/var.py +16 -12
  200. maxframe/dataframe/reshape/__init__.py +38 -0
  201. maxframe/dataframe/{misc → reshape}/pivot.py +1 -0
  202. maxframe/dataframe/{misc → reshape}/pivot_table.py +1 -0
  203. maxframe/dataframe/reshape/unstack.py +114 -0
  204. maxframe/dataframe/sort/__init__.py +8 -0
  205. maxframe/dataframe/sort/argsort.py +62 -0
  206. maxframe/dataframe/sort/core.py +1 -0
  207. maxframe/dataframe/sort/nlargest.py +238 -0
  208. maxframe/dataframe/sort/nsmallest.py +228 -0
  209. maxframe/dataframe/statistics/__init__.py +3 -3
  210. maxframe/dataframe/statistics/corr.py +1 -0
  211. maxframe/dataframe/statistics/quantile.py +2 -2
  212. maxframe/dataframe/tests/test_typing.py +104 -0
  213. maxframe/dataframe/tests/test_utils.py +66 -2
  214. maxframe/dataframe/typing_.py +185 -0
  215. maxframe/dataframe/utils.py +95 -26
  216. maxframe/dataframe/window/aggregation.py +8 -4
  217. maxframe/dataframe/window/core.py +14 -1
  218. maxframe/dataframe/window/ewm.py +1 -3
  219. maxframe/dataframe/window/expanding.py +37 -35
  220. maxframe/dataframe/window/rolling.py +49 -39
  221. maxframe/dataframe/window/tests/test_expanding.py +1 -7
  222. maxframe/dataframe/window/tests/test_rolling.py +1 -1
  223. maxframe/env.py +7 -4
  224. maxframe/errors.py +2 -2
  225. maxframe/io/odpsio/schema.py +9 -3
  226. maxframe/io/odpsio/tableio.py +7 -2
  227. maxframe/io/odpsio/tests/test_schema.py +198 -83
  228. maxframe/learn/__init__.py +10 -2
  229. maxframe/learn/cluster/__init__.py +15 -0
  230. maxframe/learn/cluster/_kmeans.py +782 -0
  231. maxframe/learn/contrib/llm/core.py +2 -0
  232. maxframe/learn/contrib/xgboost/core.py +86 -1
  233. maxframe/learn/contrib/xgboost/train.py +5 -2
  234. maxframe/learn/core.py +66 -0
  235. maxframe/learn/linear_model/_base.py +58 -1
  236. maxframe/learn/linear_model/_lin_reg.py +1 -1
  237. maxframe/learn/metrics/__init__.py +6 -0
  238. maxframe/learn/metrics/_classification.py +145 -0
  239. maxframe/learn/metrics/_ranking.py +477 -0
  240. maxframe/learn/metrics/_scorer.py +60 -0
  241. maxframe/learn/metrics/pairwise/__init__.py +21 -0
  242. maxframe/learn/metrics/pairwise/core.py +77 -0
  243. maxframe/learn/metrics/pairwise/cosine.py +115 -0
  244. maxframe/learn/metrics/pairwise/euclidean.py +176 -0
  245. maxframe/learn/metrics/pairwise/haversine.py +96 -0
  246. maxframe/learn/metrics/pairwise/manhattan.py +80 -0
  247. maxframe/learn/metrics/pairwise/pairwise.py +127 -0
  248. maxframe/learn/metrics/pairwise/pairwise_distances_topk.py +121 -0
  249. maxframe/learn/metrics/pairwise/rbf_kernel.py +51 -0
  250. maxframe/learn/metrics/tests/__init__.py +13 -0
  251. maxframe/learn/metrics/tests/test_scorer.py +26 -0
  252. maxframe/learn/utils/__init__.py +1 -1
  253. maxframe/learn/utils/checks.py +1 -2
  254. maxframe/learn/utils/core.py +59 -0
  255. maxframe/learn/utils/extmath.py +37 -0
  256. maxframe/learn/utils/odpsio.py +193 -0
  257. maxframe/learn/utils/validation.py +2 -2
  258. maxframe/lib/compat.py +40 -0
  259. maxframe/lib/dtypes_extension/__init__.py +16 -1
  260. maxframe/lib/dtypes_extension/_fake_arrow_dtype.py +604 -0
  261. maxframe/lib/dtypes_extension/blob.py +304 -0
  262. maxframe/lib/dtypes_extension/dtypes.py +40 -0
  263. maxframe/lib/dtypes_extension/tests/test_blob.py +88 -0
  264. maxframe/lib/dtypes_extension/tests/test_dtypes.py +16 -1
  265. maxframe/lib/dtypes_extension/tests/test_fake_arrow_dtype.py +75 -0
  266. maxframe/lib/filesystem/_oss_lib/common.py +122 -50
  267. maxframe/lib/filesystem/_oss_lib/glob.py +1 -1
  268. maxframe/lib/filesystem/_oss_lib/handle.py +21 -25
  269. maxframe/lib/filesystem/base.py +1 -1
  270. maxframe/lib/filesystem/core.py +1 -1
  271. maxframe/lib/filesystem/oss.py +115 -46
  272. maxframe/lib/filesystem/tests/test_oss.py +74 -36
  273. maxframe/lib/mmh3.cp311-win_amd64.pyd +0 -0
  274. maxframe/lib/wrapped_pickle.py +10 -0
  275. maxframe/opcodes.py +33 -15
  276. maxframe/protocol.py +12 -0
  277. maxframe/serialization/__init__.py +11 -2
  278. maxframe/serialization/arrow.py +38 -13
  279. maxframe/serialization/blob.py +32 -0
  280. maxframe/serialization/core.cp311-win_amd64.pyd +0 -0
  281. maxframe/serialization/core.pyx +39 -1
  282. maxframe/serialization/exception.py +2 -4
  283. maxframe/serialization/numpy.py +11 -0
  284. maxframe/serialization/pandas.py +46 -9
  285. maxframe/serialization/serializables/core.py +2 -2
  286. maxframe/serialization/tests/test_serial.py +29 -2
  287. maxframe/tensor/__init__.py +38 -8
  288. maxframe/tensor/arithmetic/__init__.py +19 -10
  289. maxframe/tensor/arithmetic/iscomplexobj.py +53 -0
  290. maxframe/tensor/arithmetic/tests/test_arithmetic.py +6 -0
  291. maxframe/tensor/core.py +3 -2
  292. maxframe/tensor/datasource/tests/test_datasource.py +2 -1
  293. maxframe/tensor/extensions/__init__.py +2 -0
  294. maxframe/tensor/extensions/apply_chunk.py +3 -3
  295. maxframe/tensor/extensions/rebalance.py +65 -0
  296. maxframe/tensor/fft/__init__.py +32 -0
  297. maxframe/tensor/fft/core.py +168 -0
  298. maxframe/tensor/fft/fft.py +112 -0
  299. maxframe/tensor/fft/fft2.py +118 -0
  300. maxframe/tensor/fft/fftfreq.py +80 -0
  301. maxframe/tensor/fft/fftn.py +123 -0
  302. maxframe/tensor/fft/fftshift.py +79 -0
  303. maxframe/tensor/fft/hfft.py +112 -0
  304. maxframe/tensor/fft/ifft.py +114 -0
  305. maxframe/tensor/fft/ifft2.py +115 -0
  306. maxframe/tensor/fft/ifftn.py +123 -0
  307. maxframe/tensor/fft/ifftshift.py +73 -0
  308. maxframe/tensor/fft/ihfft.py +93 -0
  309. maxframe/tensor/fft/irfft.py +118 -0
  310. maxframe/tensor/fft/irfft2.py +62 -0
  311. maxframe/tensor/fft/irfftn.py +114 -0
  312. maxframe/tensor/fft/rfft.py +116 -0
  313. maxframe/tensor/fft/rfft2.py +63 -0
  314. maxframe/tensor/fft/rfftfreq.py +87 -0
  315. maxframe/tensor/fft/rfftn.py +113 -0
  316. maxframe/tensor/indexing/fill_diagonal.py +1 -7
  317. maxframe/tensor/linalg/__init__.py +7 -0
  318. maxframe/tensor/linalg/_einsumfunc.py +1025 -0
  319. maxframe/tensor/linalg/cholesky.py +117 -0
  320. maxframe/tensor/linalg/einsum.py +339 -0
  321. maxframe/tensor/linalg/lstsq.py +100 -0
  322. maxframe/tensor/linalg/matrix_norm.py +75 -0
  323. maxframe/tensor/linalg/norm.py +249 -0
  324. maxframe/tensor/linalg/solve.py +72 -0
  325. maxframe/tensor/linalg/solve_triangular.py +2 -2
  326. maxframe/tensor/linalg/vector_norm.py +113 -0
  327. maxframe/tensor/misc/__init__.py +24 -1
  328. maxframe/tensor/misc/argwhere.py +72 -0
  329. maxframe/tensor/misc/array_split.py +46 -0
  330. maxframe/tensor/misc/broadcast_arrays.py +57 -0
  331. maxframe/tensor/misc/copyto.py +130 -0
  332. maxframe/tensor/misc/delete.py +104 -0
  333. maxframe/tensor/misc/dsplit.py +68 -0
  334. maxframe/tensor/misc/ediff1d.py +74 -0
  335. maxframe/tensor/misc/expand_dims.py +85 -0
  336. maxframe/tensor/misc/flip.py +90 -0
  337. maxframe/tensor/misc/fliplr.py +64 -0
  338. maxframe/tensor/misc/flipud.py +68 -0
  339. maxframe/tensor/misc/hsplit.py +85 -0
  340. maxframe/tensor/misc/insert.py +139 -0
  341. maxframe/tensor/misc/moveaxis.py +83 -0
  342. maxframe/tensor/misc/result_type.py +88 -0
  343. maxframe/tensor/misc/roll.py +124 -0
  344. maxframe/tensor/misc/rollaxis.py +77 -0
  345. maxframe/tensor/misc/shape.py +89 -0
  346. maxframe/tensor/misc/split.py +190 -0
  347. maxframe/tensor/misc/tile.py +109 -0
  348. maxframe/tensor/misc/vsplit.py +74 -0
  349. maxframe/tensor/reduction/array_equal.py +2 -1
  350. maxframe/tensor/sort/__init__.py +2 -0
  351. maxframe/tensor/sort/argpartition.py +98 -0
  352. maxframe/tensor/sort/partition.py +228 -0
  353. maxframe/tensor/spatial/__init__.py +15 -0
  354. maxframe/tensor/spatial/distance/__init__.py +17 -0
  355. maxframe/tensor/spatial/distance/cdist.py +421 -0
  356. maxframe/tensor/spatial/distance/pdist.py +398 -0
  357. maxframe/tensor/spatial/distance/squareform.py +153 -0
  358. maxframe/tensor/special/__init__.py +159 -21
  359. maxframe/tensor/special/airy.py +55 -0
  360. maxframe/tensor/special/bessel.py +199 -0
  361. maxframe/tensor/special/core.py +65 -4
  362. maxframe/tensor/special/ellip_func_integrals.py +155 -0
  363. maxframe/tensor/special/ellip_harm.py +55 -0
  364. maxframe/tensor/special/err_fresnel.py +223 -0
  365. maxframe/tensor/special/gamma_funcs.py +303 -0
  366. maxframe/tensor/special/hypergeometric_funcs.py +69 -0
  367. maxframe/tensor/special/info_theory.py +189 -0
  368. maxframe/tensor/special/misc.py +21 -0
  369. maxframe/tensor/statistics/__init__.py +6 -0
  370. maxframe/tensor/statistics/corrcoef.py +77 -0
  371. maxframe/tensor/statistics/cov.py +222 -0
  372. maxframe/tensor/statistics/digitize.py +126 -0
  373. maxframe/tensor/statistics/histogram.py +520 -0
  374. maxframe/tensor/statistics/median.py +85 -0
  375. maxframe/tensor/statistics/ptp.py +89 -0
  376. maxframe/tensor/utils.py +3 -3
  377. maxframe/tests/test_utils.py +43 -1
  378. maxframe/tests/utils.py +0 -2
  379. maxframe/typing_.py +2 -0
  380. maxframe/udf.py +27 -2
  381. maxframe/utils.py +193 -19
  382. {maxframe-2.0.0b2.dist-info → maxframe-2.2.0.dist-info}/METADATA +3 -2
  383. {maxframe-2.0.0b2.dist-info → maxframe-2.2.0.dist-info}/RECORD +391 -236
  384. maxframe_client/fetcher.py +35 -4
  385. maxframe_client/session/odps.py +7 -2
  386. maxframe_client/tests/test_fetcher.py +76 -3
  387. maxframe_client/tests/test_session.py +4 -1
  388. /maxframe/dataframe/{misc → reshape}/melt.py +0 -0
  389. /maxframe/dataframe/{misc → reshape}/stack.py +0 -0
  390. {maxframe-2.0.0b2.dist-info → maxframe-2.2.0.dist-info}/WHEEL +0 -0
  391. {maxframe-2.0.0b2.dist-info → maxframe-2.2.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,185 @@
1
+ # Copyright 1999-2025 Alibaba Group Holding Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from ... import opcodes
16
+ from ...core import OutputType
17
+ from ..utils import validate_axis
18
+ from .core import DataFrameReduction, DataFrameReductionMixin, ReductionCallable
19
+
20
+
21
+ class DataFrameIdxMin(DataFrameReduction, DataFrameReductionMixin):
22
+ _op_type_ = opcodes.IDXMIN
23
+ _func_name = "idxmin"
24
+
25
+ @property
26
+ def is_atomic(self):
27
+ return True
28
+
29
+ def get_reduction_args(self, axis=None):
30
+ args = dict(skipna=self.skipna)
31
+ if self.inputs and self.inputs[0].ndim > 1:
32
+ args["axis"] = axis
33
+ return {k: v for k, v in args.items() if v is not None}
34
+
35
+ @classmethod
36
+ def get_reduction_callable(cls, op):
37
+ func_name = getattr(op, "_func_name")
38
+ kw = dict(skipna=op.skipna)
39
+ kw = {k: v for k, v in kw.items() if v is not None}
40
+ return ReductionCallable(func_name=func_name, kwargs=kw)
41
+
42
+
43
+ def idxmin_dataframe(df, axis=0, skipna=True):
44
+ """
45
+ Return index of first occurrence of minimum over requested axis.
46
+
47
+ NA/null values are excluded.
48
+
49
+ Parameters
50
+ ----------
51
+ axis : {0 or 'index', 1 or 'columns'}, default 0
52
+ The axis to use. 0 or 'index' for row-wise, 1 or 'columns' for column-wise.
53
+ skipna : bool, default True
54
+ Exclude NA/null values. If an entire row/column is NA, the result
55
+ will be NA.
56
+
57
+ Returns
58
+ -------
59
+ Series
60
+ Indexes of minima along the specified axis.
61
+
62
+ Raises
63
+ ------
64
+ ValueError
65
+ * If the row/column is empty
66
+
67
+ See Also
68
+ --------
69
+ Series.idxmin : Return index of the minimum element.
70
+
71
+ Notes
72
+ -----
73
+ This method is the DataFrame version of ``ndarray.argmin``.
74
+
75
+ Examples
76
+ --------
77
+ Consider a dataset containing food consumption in Argentina.
78
+
79
+ >>> import maxframe.dataframe as md
80
+ >>> df = md.DataFrame({'consumption': [10.51, 103.11, 55.48],
81
+ ... 'co2_emissions': [37.2, 19.66, 1712]},
82
+ ... index=['Pork', 'Wheat Products', 'Beef'])
83
+
84
+ >>> df.execute()
85
+ consumption co2_emissions
86
+ Pork 10.51 37.20
87
+ Wheat Products 103.11 19.66
88
+ Beef 55.48 1712.00
89
+
90
+ By default, it returns the index for the minimum value in each column.
91
+
92
+ >>> df.idxmin().execute()
93
+ consumption Pork
94
+ co2_emissions Wheat Products
95
+ dtype: object
96
+
97
+ To return the index for the minimum value in each row, use ``axis="columns"``.
98
+
99
+ >>> df.idxmin(axis="columns").execute()
100
+ Pork consumption
101
+ Wheat Products co2_emissions
102
+ Beef consumption
103
+ dtype: object
104
+ """
105
+ axis = validate_axis(axis, df)
106
+ op = DataFrameIdxMin(
107
+ axis=axis,
108
+ skipna=skipna,
109
+ output_types=[OutputType.series],
110
+ )
111
+ return op(df)
112
+
113
+
114
+ def idxmin_series(series, axis=0, skipna=True):
115
+ """
116
+ Return the row label of the minimum value.
117
+
118
+ If multiple values equal the minimum, the first row label with that
119
+ value is returned.
120
+
121
+ Parameters
122
+ ----------
123
+ axis : int, default 0
124
+ For compatibility with DataFrame.idxmin. Redundant for application
125
+ on Series.
126
+ skipna : bool, default True
127
+ Exclude NA/null values. If the entire Series is NA, the result
128
+ will be NA.
129
+ *args, **kwargs
130
+ Additional arguments and keywords have no effect but might be
131
+ accepted for compatibility with NumPy.
132
+
133
+ Returns
134
+ -------
135
+ Index
136
+ Label of the minimum value.
137
+
138
+ Raises
139
+ ------
140
+ ValueError
141
+ If the Series is empty.
142
+
143
+ See Also
144
+ --------
145
+ numpy.argmin : Return indices of the minimum values
146
+ along the given axis.
147
+ DataFrame.idxmin : Return index of first occurrence of minimum
148
+ over requested axis.
149
+ Series.idxmin : Return index *label* of the first occurrence
150
+ of minimum of values.
151
+
152
+ Notes
153
+ -----
154
+ This method is the Series version of ``ndarray.argmin``. This method
155
+ returns the label of the minimum, while ``ndarray.argmin`` returns
156
+ the position. To get the position, use ``series.values.argmin()``.
157
+
158
+ Examples
159
+ --------
160
+ >>> import maxframe.dataframe as md
161
+ >>> s = md.Series(data=[1, None, 4, 3, 4],
162
+ ... index=['A', 'B', 'C', 'D', 'E'])
163
+ >>> s.execute()
164
+ A 1.0
165
+ B NaN
166
+ C 4.0
167
+ D 3.0
168
+ E 4.0
169
+ dtype: float64
170
+
171
+ >>> s.idxmin().execute()
172
+ 'C'
173
+
174
+ If `skipna` is False and there is an NA value in the data,
175
+ the function returns ``nan``.
176
+
177
+ >>> s.idxmin(skipna=False).execute()
178
+ nan
179
+ """
180
+ validate_axis(axis, series)
181
+ op = DataFrameIdxMin(
182
+ dropna=skipna,
183
+ output_types=[OutputType.scalar],
184
+ )
185
+ return op(series)
@@ -17,10 +17,42 @@ import numpy as np
17
17
  from ... import opcodes
18
18
  from ...core import ENTITY_TYPE, OutputType
19
19
  from ...serialization.serializables import BoolField
20
- from .core import DataFrameReductionMixin, DataFrameReductionOperator
20
+ from .core import DataFrameReduction, DataFrameReductionMixin, ReductionCallable
21
21
 
22
22
 
23
- class DataFrameKurtosis(DataFrameReductionOperator, DataFrameReductionMixin):
23
+ class KurtosisReductionCallable(ReductionCallable):
24
+ def __call__(self, value):
25
+ from .aggregation import where_function
26
+
27
+ skipna = self.kwargs["skipna"]
28
+ bias = self.kwargs["bias"]
29
+ fisher = self.kwargs["fisher"]
30
+
31
+ cnt = value.count()
32
+ mean = value.mean(skipna=skipna)
33
+ divided = (
34
+ (value**4).mean(skipna=skipna)
35
+ - 4 * (value**3).mean(skipna=skipna) * mean
36
+ + 6 * (value**2).mean(skipna=skipna) * mean**2
37
+ - 3 * mean**4
38
+ )
39
+ var = value.var(skipna=skipna, ddof=0)
40
+ if isinstance(var, ENTITY_TYPE) or var > 0:
41
+ val = where_function(var > 0, divided / var**2, np.nan)
42
+ else:
43
+ val = np.nan
44
+ if not bias:
45
+ val = where_function(
46
+ (var > 0) & (cnt > 3),
47
+ (val * (cnt**2 - 1) - 3 * (cnt - 1) ** 2) / (cnt - 2) / (cnt - 3),
48
+ np.nan,
49
+ )
50
+ if not fisher:
51
+ val += 3
52
+ return val
53
+
54
+
55
+ class DataFrameKurtosis(DataFrameReduction, DataFrameReductionMixin):
24
56
  _op_type_ = opcodes.KURTOSIS
25
57
  _func_name = "kurt"
26
58
 
@@ -29,35 +61,10 @@ class DataFrameKurtosis(DataFrameReductionOperator, DataFrameReductionMixin):
29
61
 
30
62
  @classmethod
31
63
  def get_reduction_callable(cls, op):
32
- from .aggregation import where_function
33
-
34
64
  skipna, bias, fisher = op.skipna, op.bias, op.fisher
35
-
36
- def kurt(x):
37
- cnt = x.count()
38
- mean = x.mean(skipna=skipna)
39
- divided = (
40
- (x**4).mean(skipna=skipna)
41
- - 4 * (x**3).mean(skipna=skipna) * mean
42
- + 6 * (x**2).mean(skipna=skipna) * mean**2
43
- - 3 * mean**4
44
- )
45
- var = x.var(skipna=skipna, ddof=0)
46
- if isinstance(var, ENTITY_TYPE) or var > 0:
47
- val = where_function(var > 0, divided / var**2, np.nan)
48
- else:
49
- val = np.nan
50
- if not bias:
51
- val = where_function(
52
- (var > 0) & (cnt > 3),
53
- (val * (cnt**2 - 1) - 3 * (cnt - 1) ** 2) / (cnt - 2) / (cnt - 3),
54
- np.nan,
55
- )
56
- if not fisher:
57
- val += 3
58
- return val
59
-
60
- return kurt
65
+ return KurtosisReductionCallable(
66
+ func_name="kurt", kwargs=dict(skipna=skipna, bias=bias, fisher=fisher)
67
+ )
61
68
 
62
69
 
63
70
  def kurt_series(
@@ -14,10 +14,10 @@
14
14
 
15
15
  from ... import opcodes
16
16
  from ...core import OutputType
17
- from .core import DataFrameReductionMixin, DataFrameReductionOperator
17
+ from .core import DataFrameReduction, DataFrameReductionMixin
18
18
 
19
19
 
20
- class DataFrameMax(DataFrameReductionOperator, DataFrameReductionMixin):
20
+ class DataFrameMax(DataFrameReduction, DataFrameReductionMixin):
21
21
  _op_type_ = opcodes.MAX
22
22
  _func_name = "max"
23
23
 
@@ -14,21 +14,23 @@
14
14
 
15
15
  from ... import opcodes
16
16
  from ...core import OutputType
17
- from .core import DataFrameReductionMixin, DataFrameReductionOperator
17
+ from .core import DataFrameReduction, DataFrameReductionMixin, ReductionCallable
18
18
 
19
19
 
20
- class DataFrameMean(DataFrameReductionOperator, DataFrameReductionMixin):
20
+ class MeanReductionCallable(ReductionCallable):
21
+ def __call__(self, value):
22
+ skipna = self.kwargs["skipna"]
23
+ return value.sum(skipna=skipna) / value.count()
24
+
25
+
26
+ class DataFrameMean(DataFrameReduction, DataFrameReductionMixin):
21
27
  _op_type_ = opcodes.MEAN
22
28
  _func_name = "mean"
23
29
 
24
30
  @classmethod
25
31
  def get_reduction_callable(cls, op):
26
32
  skipna = op.skipna
27
-
28
- def mean(x):
29
- return x.sum(skipna=skipna) / x.count()
30
-
31
- return mean
33
+ return MeanReductionCallable(func_name="mean", kwargs=dict(skipna=skipna))
32
34
 
33
35
 
34
36
  def mean_series(df, axis=None, skipna=True, level=None, method=None):
@@ -14,10 +14,10 @@
14
14
 
15
15
  from ... import opcodes
16
16
  from ...core import OutputType
17
- from .core import DataFrameReductionMixin, DataFrameReductionOperator
17
+ from .core import DataFrameReduction, DataFrameReductionMixin
18
18
 
19
19
 
20
- class DataFrameMedian(DataFrameReductionOperator, DataFrameReductionMixin):
20
+ class DataFrameMedian(DataFrameReduction, DataFrameReductionMixin):
21
21
  _op_type_ = opcodes.MEDIAN
22
22
  _func_name = "median"
23
23
 
@@ -14,10 +14,10 @@
14
14
 
15
15
  from ... import opcodes
16
16
  from ...core import OutputType
17
- from .core import DataFrameReductionMixin, DataFrameReductionOperator
17
+ from .core import DataFrameReduction, DataFrameReductionMixin
18
18
 
19
19
 
20
- class DataFrameMin(DataFrameReductionOperator, DataFrameReductionMixin):
20
+ class DataFrameMin(DataFrameReduction, DataFrameReductionMixin):
21
21
  _op_type_ = opcodes.MIN
22
22
  _func_name = "min"
23
23
 
@@ -22,12 +22,12 @@ from ...config import options
22
22
  from ...core import OutputType
23
23
  from ...serialization.serializables import BoolField
24
24
  from ...utils import lazy_import
25
- from .core import DataFrameReductionMixin, DataFrameReductionOperator
25
+ from .core import DataFrameReduction, DataFrameReductionMixin, ReductionCallable
26
26
 
27
27
  cudf = lazy_import("cudf")
28
28
 
29
29
 
30
- class DataFrameNunique(DataFrameReductionOperator, DataFrameReductionMixin):
30
+ class DataFrameNunique(DataFrameReduction, DataFrameReductionMixin):
31
31
  _op_type_ = opcodes.NUNIQUE
32
32
  _func_name = "nunique"
33
33
 
@@ -38,17 +38,18 @@ class DataFrameNunique(DataFrameReductionOperator, DataFrameReductionMixin):
38
38
  def is_atomic(self):
39
39
  return True
40
40
 
41
+ def get_reduction_args(self, axis=None):
42
+ args = dict(dropna=self.dropna)
43
+ if self.inputs and self.inputs[0].ndim > 1:
44
+ args["axis"] = axis
45
+ return {k: v for k, v in args.items() if v is not None}
46
+
41
47
  @classmethod
42
48
  def get_reduction_callable(cls, op):
43
49
  func_name = getattr(op, "_func_name")
44
50
  kw = dict(dropna=op.dropna)
45
51
  kw = {k: v for k, v in kw.items() if v is not None}
46
-
47
- def fun(value):
48
- return value.nunique(**kw)
49
-
50
- fun.__name__ = func_name
51
- return fun
52
+ return ReductionCallable(func_name=func_name, kwargs=kw)
52
53
 
53
54
 
54
55
  def nunique_dataframe(df, axis=0, dropna=True):
@@ -16,11 +16,23 @@ import numpy as np
16
16
 
17
17
  from ... import opcodes
18
18
  from ...core import OutputType
19
- from .aggregation import where_function
20
- from .core import DataFrameReductionMixin, DataFrameReductionOperator
19
+ from .core import DataFrameReduction, DataFrameReductionMixin, ReductionCallable
21
20
 
22
21
 
23
- class DataFrameProd(DataFrameReductionOperator, DataFrameReductionMixin):
22
+ class ProdReductionCallable(ReductionCallable):
23
+ def __call__(self, value):
24
+ from .aggregation import where_function
25
+
26
+ skipna, min_count = self.kwargs["skipna"], self.kwargs["min_count"]
27
+ if min_count == 0:
28
+ return value.prod(skipna=skipna)
29
+ else:
30
+ return where_function(
31
+ value.count() >= min_count, value.prod(skipna=skipna), np.nan
32
+ )
33
+
34
+
35
+ class DataFrameProd(DataFrameReduction, DataFrameReductionMixin):
24
36
  _op_type_ = opcodes.PROD
25
37
  _func_name = "prod"
26
38
 
@@ -31,16 +43,9 @@ class DataFrameProd(DataFrameReductionOperator, DataFrameReductionMixin):
31
43
  @classmethod
32
44
  def get_reduction_callable(cls, op):
33
45
  skipna, min_count = op.skipna, op.min_count
34
-
35
- def prod(value):
36
- if min_count == 0:
37
- return value.prod(skipna=skipna)
38
- else:
39
- return where_function(
40
- value.count() >= min_count, value.prod(skipna=skipna), np.nan
41
- )
42
-
43
- return prod
46
+ return ProdReductionCallable(
47
+ func_name="prod", kwargs=dict(skipna=skipna, min_count=min_count)
48
+ )
44
49
 
45
50
 
46
51
  def prod_series(df, axis=None, skipna=True, level=None, min_count=0, method=None):
@@ -14,10 +14,10 @@
14
14
 
15
15
  from ... import opcodes
16
16
  from ...core import OutputType
17
- from .core import DataFrameReductionMixin, DataFrameReductionOperator
17
+ from .core import DataFrameReduction, DataFrameReductionMixin
18
18
 
19
19
 
20
- class DataFrameSize(DataFrameReductionOperator, DataFrameReductionMixin):
20
+ class DataFrameSize(DataFrameReduction, DataFrameReductionMixin):
21
21
  _op_type_ = opcodes.REDUCTION_SIZE
22
22
  _func_name = "size"
23
23
 
@@ -15,10 +15,18 @@
15
15
  from ... import opcodes
16
16
  from ...core import OutputType
17
17
  from ...serialization.serializables import Int32Field
18
- from .core import DataFrameReductionMixin, DataFrameReductionOperator
18
+ from .core import DataFrameReduction, DataFrameReductionMixin, ReductionCallable
19
19
 
20
20
 
21
- class DataFrameSem(DataFrameReductionOperator, DataFrameReductionMixin):
21
+ class SemReductionCallable(ReductionCallable):
22
+ def __call__(self, value):
23
+ skipna, ddof = self.kwargs["skipna"], self.kwargs["ddof"]
24
+ var = value.var(skipna=skipna, ddof=ddof)
25
+ cnt = value.count()
26
+ return (var / cnt) ** 0.5
27
+
28
+
29
+ class DataFrameSem(DataFrameReduction, DataFrameReductionMixin):
22
30
  _op_type_ = opcodes.SEM
23
31
  _func_name = "sem"
24
32
 
@@ -27,13 +35,9 @@ class DataFrameSem(DataFrameReductionOperator, DataFrameReductionMixin):
27
35
  @classmethod
28
36
  def get_reduction_callable(cls, op: "DataFrameSem"):
29
37
  skipna, ddof = op.skipna, op.ddof
30
-
31
- def sem(x):
32
- var = x.var(skipna=skipna, ddof=ddof)
33
- cnt = x.count()
34
- return (var / cnt) ** 0.5
35
-
36
- return sem
38
+ return SemReductionCallable(
39
+ func_name="sem", kwargs={"skipna": skipna, "ddof": ddof}
40
+ )
37
41
 
38
42
 
39
43
  def sem_series(series, axis=None, skipna=True, level=None, ddof=1, method=None):
@@ -17,10 +17,36 @@ import numpy as np
17
17
  from ... import opcodes
18
18
  from ...core import ENTITY_TYPE, OutputType
19
19
  from ...serialization.serializables import BoolField
20
- from .core import DataFrameReductionMixin, DataFrameReductionOperator
20
+ from .core import DataFrameReduction, DataFrameReductionMixin, ReductionCallable
21
21
 
22
22
 
23
- class DataFrameSkew(DataFrameReductionOperator, DataFrameReductionMixin):
23
+ class SkewReductionCallable(ReductionCallable):
24
+ def __call__(self, value):
25
+ from .aggregation import where_function
26
+
27
+ skipna, bias = self.kwargs["skipna"], self.kwargs["bias"]
28
+ cnt = value.count()
29
+ mean = value.mean(skipna=skipna)
30
+ divided = (
31
+ (value**3).mean(skipna=skipna)
32
+ - 3 * (value**2).mean(skipna=skipna) * mean
33
+ + 2 * mean**3
34
+ )
35
+ var = value.var(skipna=skipna, ddof=0)
36
+ if isinstance(var, ENTITY_TYPE) or var > 0:
37
+ val = where_function(var > 0, divided / var**1.5, np.nan)
38
+ else:
39
+ val = np.nan
40
+ if not bias:
41
+ val = where_function(
42
+ (var > 0) & (cnt > 2),
43
+ val * ((cnt * (cnt - 1)) ** 0.5 / (cnt - 2)),
44
+ np.nan,
45
+ )
46
+ return val
47
+
48
+
49
+ class DataFrameSkew(DataFrameReduction, DataFrameReductionMixin):
24
50
  _op_type_ = opcodes.SKEW
25
51
  _func_name = "skew"
26
52
 
@@ -28,32 +54,10 @@ class DataFrameSkew(DataFrameReductionOperator, DataFrameReductionMixin):
28
54
 
29
55
  @classmethod
30
56
  def get_reduction_callable(cls, op: "DataFrameSkew"):
31
- from .aggregation import where_function
32
-
33
57
  skipna, bias = op.skipna, op.bias
34
-
35
- def skew(x):
36
- cnt = x.count()
37
- mean = x.mean(skipna=skipna)
38
- divided = (
39
- (x**3).mean(skipna=skipna)
40
- - 3 * (x**2).mean(skipna=skipna) * mean
41
- + 2 * mean**3
42
- )
43
- var = x.var(skipna=skipna, ddof=0)
44
- if isinstance(var, ENTITY_TYPE) or var > 0:
45
- val = where_function(var > 0, divided / var**1.5, np.nan)
46
- else:
47
- val = np.nan
48
- if not bias:
49
- val = where_function(
50
- (var > 0) & (cnt > 2),
51
- val * ((cnt * (cnt - 1)) ** 0.5 / (cnt - 2)),
52
- np.nan,
53
- )
54
- return val
55
-
56
- return skew
58
+ return SkewReductionCallable(
59
+ func_name="skew", kwargs=dict(skipna=skipna, bias=bias)
60
+ )
57
61
 
58
62
 
59
63
  def skew_series(df, axis=None, skipna=True, level=None, bias=False, method=None):
@@ -15,10 +15,15 @@
15
15
  from ... import opcodes
16
16
  from ...core import OutputType
17
17
  from ...serialization.serializables import StringField
18
- from .core import DataFrameReductionMixin, DataFrameReductionOperator
18
+ from .core import DataFrameReduction, DataFrameReductionMixin, ReductionCallable
19
19
 
20
20
 
21
- class DataFrameStrConcat(DataFrameReductionOperator, DataFrameReductionMixin):
21
+ class StrLenReductionCallable(ReductionCallable):
22
+ def __call__(self, value):
23
+ return build_str_concat_object(value, **self.kwargs)
24
+
25
+
26
+ class DataFrameStrConcat(DataFrameReduction, DataFrameReductionMixin):
22
27
  _op_type_ = opcodes.STR_CONCAT
23
28
  _func_name = "str_concat"
24
29
 
@@ -35,11 +40,9 @@ class DataFrameStrConcat(DataFrameReductionOperator, DataFrameReductionMixin):
35
40
  @classmethod
36
41
  def get_reduction_callable(cls, op: "DataFrameStrConcat"):
37
42
  sep, na_rep = op.sep, op.na_rep
38
-
39
- def str_concat(obj):
40
- return build_str_concat_object(obj, sep=sep, na_rep=na_rep)
41
-
42
- return str_concat
43
+ return StrLenReductionCallable(
44
+ func_name="str_concat", kwargs=dict(sep=sep, na_rep=na_rep)
45
+ )
43
46
 
44
47
 
45
48
  def build_str_concat_object(df, sep=None, na_rep=None):
@@ -16,10 +16,23 @@ import numpy as np
16
16
 
17
17
  from ... import opcodes
18
18
  from ...core import OutputType
19
- from .core import DataFrameReductionMixin, DataFrameReductionOperator
19
+ from .core import DataFrameReduction, DataFrameReductionMixin, ReductionCallable
20
20
 
21
21
 
22
- class DataFrameSum(DataFrameReductionOperator, DataFrameReductionMixin):
22
+ class SumReductionCallable(ReductionCallable):
23
+ def __call__(self, value):
24
+ from .aggregation import where_function
25
+
26
+ skipna, min_count = self.kwargs["skipna"], self.kwargs["min_count"]
27
+ if min_count == 0:
28
+ return value.sum(skipna=skipna)
29
+ else:
30
+ return where_function(
31
+ value.count() >= min_count, value.sum(skipna=skipna), np.nan
32
+ )
33
+
34
+
35
+ class DataFrameSum(DataFrameReduction, DataFrameReductionMixin):
23
36
  _op_type_ = opcodes.SUM
24
37
  _func_name = "sum"
25
38
 
@@ -29,19 +42,10 @@ class DataFrameSum(DataFrameReductionOperator, DataFrameReductionMixin):
29
42
 
30
43
  @classmethod
31
44
  def get_reduction_callable(cls, op):
32
- from .aggregation import where_function
33
-
34
45
  skipna, min_count = op.skipna, op.min_count
35
-
36
- def sum_(value):
37
- if min_count == 0:
38
- return value.sum(skipna=skipna)
39
- else:
40
- return where_function(
41
- value.count() >= min_count, value.sum(skipna=skipna), np.nan
42
- )
43
-
44
- return sum_
46
+ return SumReductionCallable(
47
+ func_name="sum", kwargs=dict(skipna=skipna, min_count=min_count)
48
+ )
45
49
 
46
50
 
47
51
  def sum_series(df, axis=None, skipna=True, level=None, min_count=0, method=None):