maxframe 0.1.0b4__cp310-cp310-win32.whl → 1.0.0__cp310-cp310-win32.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 (214) hide show
  1. maxframe/__init__.py +1 -0
  2. maxframe/_utils.cp310-win32.pyd +0 -0
  3. maxframe/codegen.py +56 -5
  4. maxframe/config/config.py +78 -10
  5. maxframe/config/validators.py +42 -11
  6. maxframe/conftest.py +58 -14
  7. maxframe/core/__init__.py +2 -16
  8. maxframe/core/entity/__init__.py +1 -12
  9. maxframe/core/entity/executable.py +1 -1
  10. maxframe/core/entity/objects.py +46 -45
  11. maxframe/core/entity/output_types.py +0 -3
  12. maxframe/core/entity/tests/test_objects.py +43 -0
  13. maxframe/core/entity/tileables.py +5 -78
  14. maxframe/core/graph/__init__.py +2 -2
  15. maxframe/core/graph/builder/__init__.py +0 -1
  16. maxframe/core/graph/builder/base.py +5 -4
  17. maxframe/core/graph/builder/tileable.py +4 -4
  18. maxframe/core/graph/builder/utils.py +4 -8
  19. maxframe/core/graph/core.cp310-win32.pyd +0 -0
  20. maxframe/core/graph/core.pyx +4 -4
  21. maxframe/core/graph/entity.py +9 -33
  22. maxframe/core/operator/__init__.py +2 -9
  23. maxframe/core/operator/base.py +3 -5
  24. maxframe/core/operator/objects.py +0 -9
  25. maxframe/core/operator/utils.py +55 -0
  26. maxframe/dataframe/__init__.py +2 -1
  27. maxframe/dataframe/arithmetic/around.py +5 -17
  28. maxframe/dataframe/arithmetic/core.py +15 -7
  29. maxframe/dataframe/arithmetic/docstring.py +7 -33
  30. maxframe/dataframe/arithmetic/equal.py +4 -2
  31. maxframe/dataframe/arithmetic/greater.py +4 -2
  32. maxframe/dataframe/arithmetic/greater_equal.py +4 -2
  33. maxframe/dataframe/arithmetic/less.py +2 -2
  34. maxframe/dataframe/arithmetic/less_equal.py +4 -2
  35. maxframe/dataframe/arithmetic/not_equal.py +4 -2
  36. maxframe/dataframe/arithmetic/tests/test_arithmetic.py +39 -16
  37. maxframe/dataframe/core.py +58 -12
  38. maxframe/dataframe/datasource/date_range.py +2 -2
  39. maxframe/dataframe/datasource/read_odps_query.py +120 -24
  40. maxframe/dataframe/datasource/read_odps_table.py +9 -4
  41. maxframe/dataframe/datasource/tests/test_datasource.py +103 -8
  42. maxframe/dataframe/datastore/tests/test_to_odps.py +48 -0
  43. maxframe/dataframe/datastore/to_odps.py +28 -0
  44. maxframe/dataframe/extensions/__init__.py +5 -0
  45. maxframe/dataframe/extensions/flatjson.py +131 -0
  46. maxframe/dataframe/extensions/flatmap.py +317 -0
  47. maxframe/dataframe/extensions/reshuffle.py +1 -1
  48. maxframe/dataframe/extensions/tests/test_extensions.py +108 -3
  49. maxframe/dataframe/groupby/core.py +1 -1
  50. maxframe/dataframe/groupby/cum.py +0 -1
  51. maxframe/dataframe/groupby/fill.py +4 -1
  52. maxframe/dataframe/groupby/getitem.py +6 -0
  53. maxframe/dataframe/groupby/tests/test_groupby.py +5 -1
  54. maxframe/dataframe/groupby/transform.py +5 -1
  55. maxframe/dataframe/indexing/align.py +1 -1
  56. maxframe/dataframe/indexing/loc.py +6 -4
  57. maxframe/dataframe/indexing/rename.py +5 -28
  58. maxframe/dataframe/indexing/sample.py +0 -1
  59. maxframe/dataframe/indexing/set_index.py +68 -1
  60. maxframe/dataframe/initializer.py +11 -1
  61. maxframe/dataframe/merge/__init__.py +9 -1
  62. maxframe/dataframe/merge/concat.py +41 -31
  63. maxframe/dataframe/merge/merge.py +237 -3
  64. maxframe/dataframe/merge/tests/test_merge.py +126 -1
  65. maxframe/dataframe/misc/__init__.py +4 -0
  66. maxframe/dataframe/misc/apply.py +6 -11
  67. maxframe/dataframe/misc/case_when.py +141 -0
  68. maxframe/dataframe/misc/describe.py +2 -2
  69. maxframe/dataframe/misc/drop_duplicates.py +8 -8
  70. maxframe/dataframe/misc/eval.py +4 -0
  71. maxframe/dataframe/misc/memory_usage.py +2 -2
  72. maxframe/dataframe/misc/pct_change.py +1 -83
  73. maxframe/dataframe/misc/pivot_table.py +262 -0
  74. maxframe/dataframe/misc/tests/test_misc.py +93 -1
  75. maxframe/dataframe/misc/transform.py +1 -30
  76. maxframe/dataframe/misc/value_counts.py +4 -17
  77. maxframe/dataframe/missing/dropna.py +1 -1
  78. maxframe/dataframe/missing/fillna.py +5 -5
  79. maxframe/dataframe/operators.py +1 -17
  80. maxframe/dataframe/plotting/core.py +2 -2
  81. maxframe/dataframe/reduction/core.py +4 -3
  82. maxframe/dataframe/reduction/tests/test_reduction.py +2 -4
  83. maxframe/dataframe/sort/sort_values.py +1 -11
  84. maxframe/dataframe/statistics/corr.py +3 -3
  85. maxframe/dataframe/statistics/quantile.py +13 -19
  86. maxframe/dataframe/statistics/tests/test_statistics.py +4 -4
  87. maxframe/dataframe/tests/test_initializer.py +33 -2
  88. maxframe/dataframe/utils.py +33 -11
  89. maxframe/dataframe/window/expanding.py +5 -3
  90. maxframe/dataframe/window/tests/test_expanding.py +2 -2
  91. maxframe/errors.py +13 -0
  92. maxframe/extension.py +12 -0
  93. maxframe/io/__init__.py +13 -0
  94. maxframe/io/objects/__init__.py +24 -0
  95. maxframe/io/objects/core.py +140 -0
  96. maxframe/io/objects/tensor.py +76 -0
  97. maxframe/io/objects/tests/__init__.py +13 -0
  98. maxframe/io/objects/tests/test_object_io.py +97 -0
  99. maxframe/{odpsio → io/odpsio}/__init__.py +3 -1
  100. maxframe/{odpsio → io/odpsio}/arrow.py +43 -12
  101. maxframe/{odpsio → io/odpsio}/schema.py +38 -16
  102. maxframe/io/odpsio/tableio.py +719 -0
  103. maxframe/io/odpsio/tests/__init__.py +13 -0
  104. maxframe/{odpsio → io/odpsio}/tests/test_schema.py +75 -33
  105. maxframe/{odpsio → io/odpsio}/tests/test_tableio.py +50 -23
  106. maxframe/{odpsio → io/odpsio}/tests/test_volumeio.py +4 -6
  107. maxframe/io/odpsio/volumeio.py +63 -0
  108. maxframe/learn/contrib/__init__.py +3 -1
  109. maxframe/learn/contrib/graph/__init__.py +15 -0
  110. maxframe/learn/contrib/graph/connected_components.py +215 -0
  111. maxframe/learn/contrib/graph/tests/__init__.py +13 -0
  112. maxframe/learn/contrib/graph/tests/test_connected_components.py +53 -0
  113. maxframe/learn/contrib/llm/__init__.py +16 -0
  114. maxframe/learn/contrib/llm/core.py +54 -0
  115. maxframe/learn/contrib/llm/models/__init__.py +14 -0
  116. maxframe/learn/contrib/llm/models/dashscope.py +73 -0
  117. maxframe/learn/contrib/llm/multi_modal.py +42 -0
  118. maxframe/learn/contrib/llm/text.py +42 -0
  119. maxframe/learn/contrib/utils.py +52 -0
  120. maxframe/learn/contrib/xgboost/__init__.py +26 -0
  121. maxframe/learn/contrib/xgboost/classifier.py +110 -0
  122. maxframe/learn/contrib/xgboost/core.py +241 -0
  123. maxframe/learn/contrib/xgboost/dmatrix.py +147 -0
  124. maxframe/learn/contrib/xgboost/predict.py +121 -0
  125. maxframe/learn/contrib/xgboost/regressor.py +71 -0
  126. maxframe/learn/contrib/xgboost/tests/__init__.py +13 -0
  127. maxframe/learn/contrib/xgboost/tests/test_core.py +43 -0
  128. maxframe/learn/contrib/xgboost/train.py +132 -0
  129. maxframe/{core/operator/fuse.py → learn/core.py} +7 -10
  130. maxframe/learn/utils/__init__.py +15 -0
  131. maxframe/learn/utils/core.py +29 -0
  132. maxframe/lib/mmh3.cp310-win32.pyd +0 -0
  133. maxframe/lib/mmh3.pyi +43 -0
  134. maxframe/lib/sparse/tests/test_sparse.py +15 -15
  135. maxframe/lib/wrapped_pickle.py +2 -1
  136. maxframe/opcodes.py +11 -0
  137. maxframe/protocol.py +154 -27
  138. maxframe/remote/core.py +4 -8
  139. maxframe/serialization/__init__.py +1 -0
  140. maxframe/serialization/core.cp310-win32.pyd +0 -0
  141. maxframe/serialization/core.pxd +3 -0
  142. maxframe/serialization/core.pyi +64 -0
  143. maxframe/serialization/core.pyx +67 -26
  144. maxframe/serialization/exception.py +1 -1
  145. maxframe/serialization/pandas.py +52 -17
  146. maxframe/serialization/serializables/core.py +180 -15
  147. maxframe/serialization/serializables/field_type.py +4 -1
  148. maxframe/serialization/serializables/tests/test_serializable.py +54 -5
  149. maxframe/serialization/tests/test_serial.py +2 -1
  150. maxframe/session.py +37 -2
  151. maxframe/tensor/__init__.py +81 -2
  152. maxframe/tensor/arithmetic/isclose.py +1 -0
  153. maxframe/tensor/arithmetic/tests/test_arithmetic.py +22 -18
  154. maxframe/tensor/core.py +5 -136
  155. maxframe/tensor/datasource/array.py +7 -2
  156. maxframe/tensor/datasource/full.py +1 -1
  157. maxframe/tensor/datasource/scalar.py +1 -1
  158. maxframe/tensor/datasource/tests/test_datasource.py +1 -1
  159. maxframe/tensor/indexing/flatnonzero.py +1 -1
  160. maxframe/tensor/indexing/getitem.py +2 -0
  161. maxframe/tensor/merge/__init__.py +2 -0
  162. maxframe/tensor/merge/concatenate.py +101 -0
  163. maxframe/tensor/merge/tests/test_merge.py +30 -1
  164. maxframe/tensor/merge/vstack.py +74 -0
  165. maxframe/tensor/{base → misc}/__init__.py +4 -0
  166. maxframe/tensor/misc/atleast_1d.py +72 -0
  167. maxframe/tensor/misc/atleast_2d.py +70 -0
  168. maxframe/tensor/misc/atleast_3d.py +85 -0
  169. maxframe/tensor/misc/tests/__init__.py +13 -0
  170. maxframe/tensor/{base → misc}/transpose.py +22 -18
  171. maxframe/tensor/misc/unique.py +205 -0
  172. maxframe/tensor/operators.py +1 -7
  173. maxframe/tensor/random/core.py +1 -1
  174. maxframe/tensor/reduction/count_nonzero.py +2 -1
  175. maxframe/tensor/reduction/mean.py +1 -0
  176. maxframe/tensor/reduction/nanmean.py +1 -0
  177. maxframe/tensor/reduction/nanvar.py +2 -0
  178. maxframe/tensor/reduction/tests/test_reduction.py +12 -1
  179. maxframe/tensor/reduction/var.py +2 -0
  180. maxframe/tensor/statistics/quantile.py +2 -2
  181. maxframe/tensor/utils.py +2 -22
  182. maxframe/tests/test_protocol.py +34 -0
  183. maxframe/tests/test_utils.py +0 -12
  184. maxframe/tests/utils.py +17 -2
  185. maxframe/typing_.py +4 -1
  186. maxframe/udf.py +62 -3
  187. maxframe/utils.py +112 -86
  188. {maxframe-0.1.0b4.dist-info → maxframe-1.0.0.dist-info}/METADATA +25 -25
  189. {maxframe-0.1.0b4.dist-info → maxframe-1.0.0.dist-info}/RECORD +208 -167
  190. {maxframe-0.1.0b4.dist-info → maxframe-1.0.0.dist-info}/WHEEL +1 -1
  191. maxframe_client/__init__.py +0 -1
  192. maxframe_client/clients/framedriver.py +4 -1
  193. maxframe_client/fetcher.py +123 -54
  194. maxframe_client/session/consts.py +3 -0
  195. maxframe_client/session/graph.py +8 -2
  196. maxframe_client/session/odps.py +223 -40
  197. maxframe_client/session/task.py +108 -80
  198. maxframe_client/tests/test_fetcher.py +21 -3
  199. maxframe_client/tests/test_session.py +136 -8
  200. maxframe/core/entity/chunks.py +0 -68
  201. maxframe/core/entity/fuse.py +0 -73
  202. maxframe/core/graph/builder/chunk.py +0 -430
  203. maxframe/odpsio/tableio.py +0 -300
  204. maxframe/odpsio/volumeio.py +0 -95
  205. maxframe_client/clients/spe.py +0 -104
  206. /maxframe/{odpsio → core/entity}/tests/__init__.py +0 -0
  207. /maxframe/{tensor/base → dataframe/datastore}/tests/__init__.py +0 -0
  208. /maxframe/{odpsio → io/odpsio}/tests/test_arrow.py +0 -0
  209. /maxframe/tensor/{base → misc}/astype.py +0 -0
  210. /maxframe/tensor/{base → misc}/broadcast_to.py +0 -0
  211. /maxframe/tensor/{base → misc}/ravel.py +0 -0
  212. /maxframe/tensor/{base/tests/test_base.py → misc/tests/test_misc.py} +0 -0
  213. /maxframe/tensor/{base → misc}/where.py +0 -0
  214. {maxframe-0.1.0b4.dist-info → maxframe-1.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,72 @@
1
+ # Copyright 1999-2024 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
+ import numpy as np
16
+
17
+ from ...core import ExecutableTuple
18
+ from ..datasource import tensor as astensor
19
+
20
+
21
+ def atleast_1d(*tensors):
22
+ """
23
+ Convert inputs to tensors with at least one dimension.
24
+
25
+ Scalar inputs are converted to 1-dimensional tensors, whilst
26
+ higher-dimensional inputs are preserved.
27
+
28
+ Parameters
29
+ ----------
30
+ tensors1, tensors2, ... : array_like
31
+ One or more input tensors.
32
+
33
+ Returns
34
+ -------
35
+ ret : Tensor
36
+ An tensor, or list of tensors, each with ``a.ndim >= 1``.
37
+ Copies are made only if necessary.
38
+
39
+ See Also
40
+ --------
41
+ atleast_2d, atleast_3d
42
+
43
+ Examples
44
+ --------
45
+ >>> import maxframe.tensor as mt
46
+
47
+ >>> mt.atleast_1d(1.0).execute()
48
+ array([ 1.])
49
+
50
+ >>> x = mt.arange(9.0).reshape(3,3)
51
+ >>> mt.atleast_1d(x).execute()
52
+ array([[ 0., 1., 2.],
53
+ [ 3., 4., 5.],
54
+ [ 6., 7., 8.]])
55
+ >>> mt.atleast_1d(x) is x
56
+ True
57
+
58
+ >>> mt.atleast_1d(1, [3, 4]).execute()
59
+ [array([1]), array([3, 4])]
60
+
61
+ """
62
+ new_tensors = []
63
+ for x in tensors:
64
+ x = astensor(x)
65
+ if x.ndim == 0:
66
+ x = x[np.newaxis]
67
+
68
+ new_tensors.append(x)
69
+
70
+ if len(new_tensors) == 1:
71
+ return new_tensors[0]
72
+ return ExecutableTuple(new_tensors)
@@ -0,0 +1,70 @@
1
+ # Copyright 1999-2024 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
+ import numpy as np
16
+
17
+ from ...core import ExecutableTuple
18
+ from ..datasource import tensor as astensor
19
+
20
+
21
+ def atleast_2d(*tensors):
22
+ """
23
+ View inputs as tensors with at least two dimensions.
24
+
25
+ Parameters
26
+ ----------
27
+ tensors1, tensors2, ... : array_like
28
+ One or more array-like sequences. Non-tensor inputs are converted
29
+ to tensors. Tensors that already have two or more dimensions are
30
+ preserved.
31
+
32
+ Returns
33
+ -------
34
+ res, res2, ... : Tensor
35
+ A tensor, or list of tensors, each with ``a.ndim >= 2``.
36
+ Copies are avoided where possible, and views with two or more
37
+ dimensions are returned.
38
+
39
+ See Also
40
+ --------
41
+ atleast_1d, atleast_3d
42
+
43
+ Examples
44
+ --------
45
+ >>> import maxframe.tensor as mt
46
+
47
+ >>> mt.atleast_2d(3.0).execute()
48
+ array([[ 3.]])
49
+
50
+ >>> x = mt.arange(3.0)
51
+ >>> mt.atleast_2d(x).execute()
52
+ array([[ 0., 1., 2.]])
53
+
54
+ >>> mt.atleast_2d(1, [1, 2], [[1, 2]]).execute()
55
+ [array([[1]]), array([[1, 2]]), array([[1, 2]])]
56
+
57
+ """
58
+ new_tensors = []
59
+ for x in tensors:
60
+ x = astensor(x)
61
+ if x.ndim == 0:
62
+ x = x[np.newaxis, np.newaxis]
63
+ elif x.ndim == 1:
64
+ x = x[np.newaxis, :]
65
+
66
+ new_tensors.append(x)
67
+
68
+ if len(new_tensors) == 1:
69
+ return new_tensors[0]
70
+ return ExecutableTuple(new_tensors)
@@ -0,0 +1,85 @@
1
+ # Copyright 1999-2024 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
+
16
+ import numpy as np
17
+
18
+ from ...core import ExecutableTuple
19
+ from ..datasource import tensor as astensor
20
+
21
+
22
+ def atleast_3d(*tensors):
23
+ """
24
+ View inputs as tensors with at least three dimensions.
25
+
26
+ Parameters
27
+ ----------
28
+ tensors1, tensors2, ... : array_like
29
+ One or more tensor-like sequences. Non-tensor inputs are converted to
30
+ tensors. Tensors that already have three or more dimensions are
31
+ preserved.
32
+
33
+ Returns
34
+ -------
35
+ res1, res2, ... : Tensor
36
+ A tensor, or list of tensors, each with ``a.ndim >= 3``. Copies are
37
+ avoided where possible, and views with three or more dimensions are
38
+ returned. For example, a 1-D tensor of shape ``(N,)`` becomes a view
39
+ of shape ``(1, N, 1)``, and a 2-D tensor of shape ``(M, N)`` becomes a
40
+ view of shape ``(M, N, 1)``.
41
+
42
+ See Also
43
+ --------
44
+ atleast_1d, atleast_2d
45
+
46
+ Examples
47
+ --------
48
+ >>> import maxframe.tensor as mt
49
+
50
+ >>> mt.atleast_3d(3.0).execute()
51
+ array([[[ 3.]]])
52
+
53
+ >>> x = mt.arange(3.0)
54
+ >>> mt.atleast_3d(x).shape
55
+ (1, 3, 1)
56
+
57
+ >>> x = mt.arange(12.0).reshape(4,3)
58
+ >>> mt.atleast_3d(x).shape
59
+ (4, 3, 1)
60
+
61
+ >>> for arr in mt.atleast_3d([1, 2], [[1, 2]], [[[1, 2]]]).execute():
62
+ ... print(arr, arr.shape)
63
+ ...
64
+ [[[1]
65
+ [2]]] (1, 2, 1)
66
+ [[[1]
67
+ [2]]] (1, 2, 1)
68
+ [[[1 2]]] (1, 1, 2)
69
+
70
+ """
71
+ new_tensors = []
72
+ for x in tensors:
73
+ x = astensor(x)
74
+ if x.ndim == 0:
75
+ x = x[np.newaxis, np.newaxis, np.newaxis]
76
+ elif x.ndim == 1:
77
+ x = x[np.newaxis, :, np.newaxis]
78
+ elif x.ndim == 2:
79
+ x = x[:, :, None]
80
+
81
+ new_tensors.append(x)
82
+
83
+ if len(new_tensors) == 1:
84
+ return new_tensors[0]
85
+ return ExecutableTuple(new_tensors)
@@ -0,0 +1,13 @@
1
+ # Copyright 1999-2024 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.
@@ -1,5 +1,3 @@
1
- #!/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
1
  # Copyright 1999-2024 Alibaba Group Holding Ltd.
4
2
  #
5
3
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -66,33 +64,39 @@ class TensorTranspose(TensorHasInput, TensorOperatorMixin):
66
64
 
67
65
  def transpose(a, axes=None):
68
66
  """
69
- Permute the dimensions of a tensor.
67
+ Returns an array with axes transposed.
68
+
69
+ For a 1-D array, this returns an unchanged view of the original array, as a
70
+ transposed vector is simply the same vector.
71
+ To convert a 1-D array into a 2-D column vector, an additional dimension
72
+ must be added, e.g., ``mt.atleast_2d(a).T`` achieves this, as does
73
+ ``a[:, mt.newaxis]``.
74
+ For a 2-D array, this is the standard matrix transpose.
75
+ For an n-D array, if axes are given, their order indicates how the
76
+ axes are permuted (see Examples). If axes are not provided, then
77
+ ``transpose(a).shape == a.shape[::-1]``.
70
78
 
71
79
  Parameters
72
80
  ----------
73
81
  a : array_like
74
- Input tensor.
75
- axes : list of ints, optional
76
- By default, reverse the dimensions, otherwise permute the axes
77
- according to the values given.
82
+ Input array.
83
+ axes : tuple or list of ints, optional
84
+ If specified, it must be a tuple or list which contains a permutation
85
+ of [0,1,...,N-1] where N is the number of axes of `a`. The `i`'th axis
86
+ of the returned array will correspond to the axis numbered ``axes[i]``
87
+ of the input. If not specified, defaults to ``range(a.ndim)[::-1]``,
88
+ which reverses the order of the axes.
78
89
 
79
90
  Returns
80
91
  -------
81
- p : Tensor
82
- `a` with its axes permuted. A view is returned whenever
83
- possible.
84
-
85
- See Also
86
- --------
87
- moveaxis
88
- argsort
92
+ p : ndarray
93
+ `a` with its axes permuted. A view is returned whenever possible.
89
94
 
90
95
  Notes
91
96
  -----
92
- Use `transpose(a, argsort(axes))` to invert the transposition of tensors
97
+ Use ``transpose(a, argsort(axes))`` to invert the transposition of tensors
93
98
  when using the `axes` keyword argument.
94
99
 
95
- Transposing a 1-D array returns an unchanged view of the original tensor.
96
100
 
97
101
  Examples
98
102
  --------
@@ -121,5 +125,5 @@ def transpose(a, axes=None):
121
125
  axes = list(range(a.ndim))[::-1]
122
126
  else:
123
127
  axes = list(axes)
124
- op = TensorTranspose(axes, dtype=a.dtype, sparse=a.issparse())
128
+ op = TensorTranspose(axes, dtype=a.dtype)
125
129
  return op(a)
@@ -0,0 +1,205 @@
1
+ # Copyright 1999-2024 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
+
16
+ import numpy as np
17
+
18
+ from ... import opcodes
19
+ from ...serialization.serializables import BoolField, Int32Field
20
+ from ..core import TensorOrder
21
+ from ..operators import TensorHasInput, TensorOperatorMixin
22
+ from ..utils import validate_axis
23
+
24
+
25
+ class TensorUnique(TensorHasInput, TensorOperatorMixin):
26
+ _op_type_ = opcodes.UNIQUE
27
+
28
+ return_index = BoolField("return_index", default=False)
29
+ return_inverse = BoolField("return_inverse", default=False)
30
+ return_counts = BoolField("return_counts", default=False)
31
+ axis = Int32Field("axis", default=None)
32
+
33
+ @property
34
+ def output_limit(self):
35
+ return 1
36
+
37
+ def _gen_kws(self, input_obj, chunk=False, chunk_index=None):
38
+ kws = []
39
+
40
+ # unique tensor
41
+ shape = list(input_obj.shape)
42
+ shape[self.axis] = np.nan
43
+ kw = {"shape": tuple(shape), "dtype": input_obj.dtype, "gpu": input_obj.op.gpu}
44
+ if chunk:
45
+ idx = [0] * len(shape)
46
+ idx[self.axis] = chunk_index or 0
47
+ kw["index"] = tuple(idx)
48
+ kws.append(kw)
49
+
50
+ # unique indices tensor
51
+ if self.return_index:
52
+ kw = {
53
+ "shape": (np.nan,),
54
+ "dtype": np.dtype(np.intp),
55
+ "gpu": input_obj.op.gpu,
56
+ "type": "indices",
57
+ }
58
+ if chunk:
59
+ kw["index"] = (chunk_index or 0,)
60
+ kws.append(kw)
61
+
62
+ # unique inverse tensor
63
+ if self.return_inverse:
64
+ kw = {
65
+ "shape": (input_obj.shape[self.axis],),
66
+ "dtype": np.dtype(np.intp),
67
+ "gpu": input_obj.op.gpu,
68
+ "type": "inverse",
69
+ }
70
+ if chunk:
71
+ kw["index"] = (chunk_index or 0,)
72
+ kws.append(kw)
73
+
74
+ # unique counts tensor
75
+ if self.return_counts:
76
+ kw = {
77
+ "shape": (np.nan,),
78
+ "dtype": np.dtype(int),
79
+ "gpu": input_obj.op.gpu,
80
+ "type": "counts",
81
+ }
82
+ if chunk:
83
+ kw["index"] = (chunk_index or 0,)
84
+ kws.append(kw)
85
+
86
+ return kws
87
+
88
+ def __call__(self, ar):
89
+ from .atleast_1d import atleast_1d
90
+
91
+ ar = atleast_1d(ar)
92
+ if self.axis is None:
93
+ if ar.ndim > 1:
94
+ ar = ar.flatten()
95
+ self._axis = 0
96
+ else:
97
+ self._axis = validate_axis(ar.ndim, self._axis)
98
+
99
+ kws = self._gen_kws(self, ar)
100
+ tensors = self.new_tensors([ar], kws=kws, order=TensorOrder.C_ORDER)
101
+ if len(tensors) == 1:
102
+ return tensors[0]
103
+ return tensors
104
+
105
+
106
+ def unique(
107
+ ar,
108
+ return_index=False,
109
+ return_inverse=False,
110
+ return_counts=False,
111
+ axis=None,
112
+ ):
113
+ """
114
+ Find the unique elements of a tensor.
115
+
116
+ Returns the sorted unique elements of a tensor. There are three optional
117
+ outputs in addition to the unique elements:
118
+
119
+ * the indices of the input tensor that give the unique values
120
+ * the indices of the unique tensor that reconstruct the input tensor
121
+ * the number of times each unique value comes up in the input tensor
122
+
123
+ Parameters
124
+ ----------
125
+ ar : array_like
126
+ Input tensor. Unless `axis` is specified, this will be flattened if it
127
+ is not already 1-D.
128
+ return_index : bool, optional
129
+ If True, also return the indices of `ar` (along the specified axis,
130
+ if provided, or in the flattened tensor) that result in the unique tensor.
131
+ return_inverse : bool, optional
132
+ If True, also return the indices of the unique tensor (for the specified
133
+ axis, if provided) that can be used to reconstruct `ar`.
134
+ return_counts : bool, optional
135
+ If True, also return the number of times each unique item appears
136
+ in `ar`.
137
+ axis : int or None, optional
138
+ The axis to operate on. If None, `ar` will be flattened. If an integer,
139
+ the subarrays indexed by the given axis will be flattened and treated
140
+ as the elements of a 1-D tensor with the dimension of the given axis,
141
+ see the notes for more details. Object tensors or structured tensors
142
+ that contain objects are not supported if the `axis` kwarg is used. The
143
+ default is None.
144
+
145
+ Returns
146
+ -------
147
+ unique : Tensor
148
+ The sorted unique values.
149
+ unique_indices : Tensor, optional
150
+ The indices of the first occurrences of the unique values in the
151
+ original tensor. Only provided if `return_index` is True.
152
+ unique_inverse : Tensor, optional
153
+ The indices to reconstruct the original tensor from the
154
+ unique tensor. Only provided if `return_inverse` is True.
155
+ unique_counts : Tensor, optional
156
+ The number of times each of the unique values comes up in the
157
+ original tensor. Only provided if `return_counts` is True.
158
+
159
+ Examples
160
+ --------
161
+ >>> import maxframe.tensor as mt
162
+
163
+ >>> mt.unique([1, 1, 2, 2, 3, 3]).execute()
164
+ array([1, 2, 3])
165
+ >>> a = mt.array([[1, 1], [2, 3]])
166
+ >>> mt.unique(a).execute()
167
+ array([1, 2, 3])
168
+
169
+ Return the unique rows of a 2D tensor
170
+
171
+ >>> a = mt.array([[1, 0, 0], [1, 0, 0], [2, 3, 4]])
172
+ >>> mt.unique(a, axis=0).execute()
173
+ array([[1, 0, 0], [2, 3, 4]])
174
+
175
+ Return the indices of the original tensor that give the unique values:
176
+
177
+ >>> a = mt.array(['a', 'b', 'b', 'c', 'a'])
178
+ >>> u, indices = mt.unique(a, return_index=True)
179
+ >>> u.execute()
180
+ array(['a', 'b', 'c'],
181
+ dtype='|S1')
182
+ >>> indices.execute()
183
+ array([0, 1, 3])
184
+ >>> a[indices].execute()
185
+ array(['a', 'b', 'c'],
186
+ dtype='|S1')
187
+
188
+ Reconstruct the input array from the unique values:
189
+
190
+ >>> a = mt.array([1, 2, 6, 4, 2, 3, 2])
191
+ >>> u, indices = mt.unique(a, return_inverse=True)
192
+ >>> u.execute()
193
+ array([1, 2, 3, 4, 6])
194
+ >>> indices.execute()
195
+ array([0, 1, 4, 3, 1, 2, 1])
196
+ >>> u[indices].execute()
197
+ array([1, 2, 6, 4, 2, 3, 2])
198
+ """
199
+ op = TensorUnique(
200
+ return_index=return_index,
201
+ return_inverse=return_inverse,
202
+ return_counts=return_counts,
203
+ axis=axis,
204
+ )
205
+ return op(ar)
@@ -12,9 +12,9 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+
15
16
  from ..core import OutputType
16
17
  from ..core.operator import (
17
- Fuse,
18
18
  HasInput,
19
19
  MapReduceOperator,
20
20
  Operator,
@@ -115,9 +115,3 @@ class TensorMapReduceOperator(MapReduceOperator):
115
115
  _output_type_ = OutputType.tensor
116
116
 
117
117
  dtype = DataTypeField("dtype", default=None)
118
-
119
-
120
- class TensorFuse(Fuse):
121
- _output_type_ = OutputType.tensor
122
-
123
- dtype = DataTypeField("dtype", default=None)
@@ -19,9 +19,9 @@ from contextlib import contextmanager
19
19
  import numpy as np
20
20
 
21
21
  from ...serialization.serializables import FieldTypes, Int32Field, TupleField
22
- from ..base import broadcast_to
23
22
  from ..core import TENSOR_TYPE
24
23
  from ..datasource import tensor as astensor
24
+ from ..misc import broadcast_to
25
25
  from ..operators import TensorMapReduceOperator, TensorOperator, TensorOperatorMixin
26
26
  from ..utils import broadcast_shape
27
27
 
@@ -22,6 +22,7 @@ from .core import TensorReduction, TensorReductionMixin
22
22
 
23
23
  class TensorCountNonzero(TensorReduction, TensorReductionMixin):
24
24
  _op_type_ = opcodes.COUNT_NONZERO
25
+ _func_name = "count_nonzero"
25
26
 
26
27
  def __init__(self, dtype=None, **kw):
27
28
  if dtype is None:
@@ -77,5 +78,5 @@ def count_nonzero(a, axis=None):
77
78
  array([2, 3])
78
79
 
79
80
  """
80
- op = TensorCountNonzero(axis=axis, dtype=np.dtype(np.int_), keepdims=None)
81
+ op = TensorCountNonzero(axis=axis, dtype=np.dtype(int), keepdims=None)
81
82
  return op(a)
@@ -23,6 +23,7 @@ from .core import TensorReduction, TensorReductionMixin
23
23
 
24
24
  class TensorMean(TensorReduction, TensorReductionMixin):
25
25
  _op_type_ = opcodes.MEAN
26
+ _func_name = "mean"
26
27
 
27
28
 
28
29
  def mean(a, axis=None, dtype=None, out=None, keepdims=None):
@@ -23,6 +23,7 @@ from .core import TensorReduction, TensorReductionMixin
23
23
 
24
24
  class TensorNanMean(TensorReduction, TensorReductionMixin):
25
25
  _op_type_ = opcodes.NANMEAN
26
+ _func_name = "nanmean"
26
27
 
27
28
 
28
29
  def nanmean(a, axis=None, dtype=None, out=None, keepdims=None):
@@ -24,6 +24,7 @@ from .core import TensorReduction, TensorReductionMixin
24
24
 
25
25
  class TensorNanMoment(TensorReduction, TensorReductionMixin):
26
26
  _op_type_ = opcodes.NANMOMENT
27
+ _func_name = "nanvar"
27
28
 
28
29
  moment = Int32Field("moment", default=2)
29
30
  ddof = Int32Field("ddof", default=None)
@@ -36,6 +37,7 @@ class TensorNanMoment(TensorReduction, TensorReductionMixin):
36
37
 
37
38
  class TensorNanVar(TensorReduction, TensorReductionMixin):
38
39
  _op_type_ = opcodes.NANVAR
40
+ _func_name = "nanvar"
39
41
 
40
42
  ddof = Int32Field("ddof", default=0)
41
43
 
@@ -17,8 +17,11 @@
17
17
  import numpy as np
18
18
  import pytest
19
19
 
20
+ from maxframe.tensor.reduction.core import TensorReduction
21
+
22
+ from ....utils import collect_leaf_operators
20
23
  from ...datasource import ones, tensor
21
- from .. import all
24
+ from .. import * # noqa: F401
22
25
 
23
26
 
24
27
  def test_base_reduction():
@@ -179,3 +182,11 @@ def test_var_reduction():
179
182
 
180
183
  res1 = var(ones((10, 8, 8), chunk_size=3), axis=1)
181
184
  assert res1.shape == (10, 8)
185
+
186
+
187
+ def test_reduction_op_func_name():
188
+ # make sure all the binary op has defined the func name.
189
+
190
+ results = collect_leaf_operators(TensorReduction)
191
+ for op_type in results:
192
+ assert hasattr(op_type, "_func_name")
@@ -42,6 +42,7 @@ def reduce_var_square(var_square, avg_diff, count, op, axis, sum_func):
42
42
 
43
43
  class TensorMoment(TensorReduction, TensorReductionMixin):
44
44
  _op_type_ = opcodes.MOMENT
45
+ _func_name = "var"
45
46
 
46
47
  moment = Int32Field("moment", default=2)
47
48
  ddof = Int32Field("ddof", default=None)
@@ -54,6 +55,7 @@ class TensorMoment(TensorReduction, TensorReductionMixin):
54
55
 
55
56
  class TensorVar(TensorReduction, TensorReductionMixin):
56
57
  _op_type_ = opcodes.VAR
58
+ _func_name = "var"
57
59
 
58
60
  ddof = Int32Field("ddof", default=0)
59
61
 
@@ -16,7 +16,7 @@ from collections.abc import Iterable
16
16
 
17
17
  import numpy as np
18
18
 
19
- from ... import opcodes as OperandDef
19
+ from ... import opcodes
20
20
  from ...core import ENTITY_TYPE
21
21
  from ...serialization.serializables import AnyField, BoolField, KeyField, StringField
22
22
  from ..core import TENSOR_TYPE, TensorOrder
@@ -43,7 +43,7 @@ q_error_msg = "Quantiles must be in the range [0, 1]"
43
43
 
44
44
  class TensorQuantile(TensorOperator, TensorOperatorMixin):
45
45
  __slots__ = ("q_error_msg",)
46
- _op_type_ = OperandDef.QUANTILE
46
+ _op_type_ = opcodes.QUANTILE
47
47
 
48
48
  a = KeyField("a")
49
49
  q = AnyField("q")