maxframe 1.3.0__cp311-cp311-macosx_10_9_universal2.whl → 2.0.0__cp311-cp311-macosx_10_9_universal2.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.
- maxframe/_utils.cpython-311-darwin.so +0 -0
- maxframe/_utils.pyi +21 -0
- maxframe/_utils.pyx +4 -3
- maxframe/codegen/__init__.py +27 -0
- maxframe/{codegen.py → codegen/core.py} +49 -43
- maxframe/codegen/spe/__init__.py +16 -0
- maxframe/codegen/spe/core.py +307 -0
- maxframe/codegen/spe/dataframe/__init__.py +37 -0
- maxframe/codegen/spe/dataframe/accessors/__init__.py +15 -0
- maxframe/codegen/spe/dataframe/accessors/base.py +53 -0
- maxframe/codegen/spe/dataframe/accessors/dict_.py +194 -0
- maxframe/codegen/spe/dataframe/accessors/list_.py +80 -0
- maxframe/codegen/spe/dataframe/arithmetic.py +84 -0
- maxframe/codegen/spe/dataframe/datasource.py +181 -0
- maxframe/codegen/spe/dataframe/datastore.py +204 -0
- maxframe/codegen/spe/dataframe/extensions.py +63 -0
- maxframe/codegen/spe/dataframe/fetch.py +26 -0
- maxframe/codegen/spe/dataframe/groupby.py +224 -0
- maxframe/codegen/spe/dataframe/indexing.py +238 -0
- maxframe/codegen/spe/dataframe/merge.py +73 -0
- maxframe/codegen/spe/dataframe/misc.py +286 -0
- maxframe/codegen/spe/dataframe/missing.py +64 -0
- maxframe/codegen/spe/dataframe/reduction.py +160 -0
- maxframe/codegen/spe/dataframe/sort.py +83 -0
- maxframe/codegen/spe/dataframe/statistics.py +46 -0
- maxframe/codegen/spe/dataframe/tests/__init__.py +13 -0
- maxframe/codegen/spe/dataframe/tests/accessors/__init__.py +13 -0
- maxframe/codegen/spe/dataframe/tests/accessors/test_base.py +33 -0
- maxframe/codegen/spe/dataframe/tests/accessors/test_dict.py +310 -0
- maxframe/codegen/spe/dataframe/tests/accessors/test_list.py +137 -0
- maxframe/codegen/spe/dataframe/tests/indexing/__init__.py +13 -0
- maxframe/codegen/spe/dataframe/tests/indexing/conftest.py +58 -0
- maxframe/codegen/spe/dataframe/tests/indexing/test_getitem.py +124 -0
- maxframe/codegen/spe/dataframe/tests/indexing/test_iloc.py +76 -0
- maxframe/codegen/spe/dataframe/tests/indexing/test_indexing.py +39 -0
- maxframe/codegen/spe/dataframe/tests/indexing/test_rename.py +51 -0
- maxframe/codegen/spe/dataframe/tests/indexing/test_reset_index.py +88 -0
- maxframe/codegen/spe/dataframe/tests/indexing/test_sample.py +45 -0
- maxframe/codegen/spe/dataframe/tests/indexing/test_set_axis.py +45 -0
- maxframe/codegen/spe/dataframe/tests/indexing/test_set_index.py +41 -0
- maxframe/codegen/spe/dataframe/tests/indexing/test_setitem.py +46 -0
- maxframe/codegen/spe/dataframe/tests/misc/__init__.py +13 -0
- maxframe/codegen/spe/dataframe/tests/misc/test_apply.py +133 -0
- maxframe/codegen/spe/dataframe/tests/misc/test_drop_duplicates.py +92 -0
- maxframe/codegen/spe/dataframe/tests/misc/test_misc.py +234 -0
- maxframe/codegen/spe/dataframe/tests/missing/__init__.py +13 -0
- maxframe/codegen/spe/dataframe/tests/missing/test_checkna.py +94 -0
- maxframe/codegen/spe/dataframe/tests/missing/test_dropna.py +50 -0
- maxframe/codegen/spe/dataframe/tests/missing/test_fillna.py +94 -0
- maxframe/codegen/spe/dataframe/tests/missing/test_replace.py +45 -0
- maxframe/codegen/spe/dataframe/tests/test_arithmetic.py +73 -0
- maxframe/codegen/spe/dataframe/tests/test_datasource.py +184 -0
- maxframe/codegen/spe/dataframe/tests/test_datastore.py +200 -0
- maxframe/codegen/spe/dataframe/tests/test_extensions.py +88 -0
- maxframe/codegen/spe/dataframe/tests/test_groupby.py +225 -0
- maxframe/codegen/spe/dataframe/tests/test_merge.py +400 -0
- maxframe/codegen/spe/dataframe/tests/test_reduction.py +104 -0
- maxframe/codegen/spe/dataframe/tests/test_sort.py +159 -0
- maxframe/codegen/spe/dataframe/tests/test_statistics.py +70 -0
- maxframe/codegen/spe/dataframe/tests/test_tseries.py +29 -0
- maxframe/codegen/spe/dataframe/tests/test_value_counts.py +60 -0
- maxframe/codegen/spe/dataframe/tests/test_window.py +69 -0
- maxframe/codegen/spe/dataframe/tseries.py +46 -0
- maxframe/codegen/spe/dataframe/udf.py +62 -0
- maxframe/codegen/spe/dataframe/value_counts.py +31 -0
- maxframe/codegen/spe/dataframe/window.py +65 -0
- maxframe/codegen/spe/learn/__init__.py +15 -0
- maxframe/codegen/spe/learn/contrib/__init__.py +15 -0
- maxframe/codegen/spe/learn/contrib/lightgbm.py +160 -0
- maxframe/codegen/spe/learn/contrib/models.py +41 -0
- maxframe/codegen/spe/learn/contrib/pytorch.py +49 -0
- maxframe/codegen/spe/learn/contrib/tests/__init__.py +13 -0
- maxframe/codegen/spe/learn/contrib/tests/test_lightgbm.py +123 -0
- maxframe/codegen/spe/learn/contrib/tests/test_models.py +41 -0
- maxframe/codegen/spe/learn/contrib/tests/test_pytorch.py +53 -0
- maxframe/codegen/spe/learn/contrib/tests/test_xgboost.py +98 -0
- maxframe/codegen/spe/learn/contrib/xgboost.py +152 -0
- maxframe/codegen/spe/learn/metrics/__init__.py +15 -0
- maxframe/codegen/spe/learn/metrics/_classification.py +120 -0
- maxframe/codegen/spe/learn/metrics/tests/__init__.py +13 -0
- maxframe/codegen/spe/learn/metrics/tests/test_classification.py +93 -0
- maxframe/codegen/spe/learn/model_selection/__init__.py +13 -0
- maxframe/codegen/spe/learn/model_selection/tests/__init__.py +13 -0
- maxframe/codegen/spe/learn/model_selection/tests/test_split.py +41 -0
- maxframe/codegen/spe/learn/preprocessing/__init__.py +15 -0
- maxframe/codegen/spe/learn/preprocessing/_data.py +37 -0
- maxframe/codegen/spe/learn/preprocessing/_label.py +47 -0
- maxframe/codegen/spe/learn/preprocessing/tests/__init__.py +13 -0
- maxframe/codegen/spe/learn/preprocessing/tests/test_data.py +31 -0
- maxframe/codegen/spe/learn/preprocessing/tests/test_label.py +43 -0
- maxframe/codegen/spe/learn/utils/__init__.py +15 -0
- maxframe/codegen/spe/learn/utils/checks.py +55 -0
- maxframe/codegen/spe/learn/utils/multiclass.py +60 -0
- maxframe/codegen/spe/learn/utils/shuffle.py +85 -0
- maxframe/codegen/spe/learn/utils/sparsefuncs.py +35 -0
- maxframe/codegen/spe/learn/utils/tests/__init__.py +13 -0
- maxframe/codegen/spe/learn/utils/tests/test_checks.py +48 -0
- maxframe/codegen/spe/learn/utils/tests/test_multiclass.py +52 -0
- maxframe/codegen/spe/learn/utils/tests/test_shuffle.py +50 -0
- maxframe/codegen/spe/learn/utils/tests/test_sparsefuncs.py +34 -0
- maxframe/codegen/spe/learn/utils/tests/test_validation.py +44 -0
- maxframe/codegen/spe/learn/utils/validation.py +35 -0
- maxframe/codegen/spe/objects.py +26 -0
- maxframe/codegen/spe/remote.py +29 -0
- maxframe/codegen/spe/tensor/__init__.py +28 -0
- maxframe/codegen/spe/tensor/arithmetic.py +95 -0
- maxframe/codegen/spe/tensor/core.py +41 -0
- maxframe/codegen/spe/tensor/datasource.py +165 -0
- maxframe/codegen/spe/tensor/extensions.py +35 -0
- maxframe/codegen/spe/tensor/fetch.py +26 -0
- maxframe/codegen/spe/tensor/indexing.py +63 -0
- maxframe/codegen/spe/tensor/linalg.py +63 -0
- maxframe/codegen/spe/tensor/merge.py +31 -0
- maxframe/codegen/spe/tensor/misc.py +121 -0
- maxframe/codegen/spe/tensor/random.py +29 -0
- maxframe/codegen/spe/tensor/reduction.py +39 -0
- maxframe/codegen/spe/tensor/reshape.py +26 -0
- maxframe/codegen/spe/tensor/sort.py +42 -0
- maxframe/codegen/spe/tensor/special.py +35 -0
- maxframe/codegen/spe/tensor/statistics.py +24 -0
- maxframe/codegen/spe/tensor/tests/__init__.py +13 -0
- maxframe/codegen/spe/tensor/tests/test_arithmetic.py +103 -0
- maxframe/codegen/spe/tensor/tests/test_datasource.py +99 -0
- maxframe/codegen/spe/tensor/tests/test_extensions.py +37 -0
- maxframe/codegen/spe/tensor/tests/test_indexing.py +44 -0
- maxframe/codegen/spe/tensor/tests/test_linalg.py +38 -0
- maxframe/codegen/spe/tensor/tests/test_merge.py +28 -0
- maxframe/codegen/spe/tensor/tests/test_misc.py +94 -0
- maxframe/codegen/spe/tensor/tests/test_random.py +55 -0
- maxframe/codegen/spe/tensor/tests/test_reduction.py +65 -0
- maxframe/codegen/spe/tensor/tests/test_reshape.py +39 -0
- maxframe/codegen/spe/tensor/tests/test_sort.py +49 -0
- maxframe/codegen/spe/tensor/tests/test_special.py +28 -0
- maxframe/codegen/spe/tensor/tests/test_statistics.py +29 -0
- maxframe/codegen/spe/tests/__init__.py +13 -0
- maxframe/codegen/spe/tests/test_remote.py +29 -0
- maxframe/codegen/spe/tests/test_spe_codegen.py +141 -0
- maxframe/codegen/spe/utils.py +54 -0
- maxframe/codegen/tests/__init__.py +13 -0
- maxframe/{tests → codegen/tests}/test_codegen.py +3 -5
- maxframe/config/__init__.py +1 -1
- maxframe/config/config.py +50 -23
- maxframe/config/tests/test_config.py +4 -12
- maxframe/config/validators.py +5 -0
- maxframe/conftest.py +38 -10
- maxframe/core/__init__.py +1 -0
- maxframe/core/context.py +110 -0
- maxframe/core/entity/__init__.py +1 -0
- maxframe/core/entity/core.py +0 -7
- maxframe/core/entity/objects.py +19 -5
- maxframe/core/entity/output_types.py +11 -0
- maxframe/core/entity/tests/test_objects.py +11 -12
- maxframe/core/entity/tileables.py +3 -1
- maxframe/core/entity/utils.py +15 -0
- maxframe/core/graph/__init__.py +6 -1
- maxframe/core/graph/builder/base.py +5 -1
- maxframe/core/graph/core.cpython-311-darwin.so +0 -0
- maxframe/core/graph/core.pyx +17 -6
- maxframe/core/graph/entity.py +18 -6
- maxframe/core/operator/__init__.py +8 -3
- maxframe/core/operator/base.py +35 -12
- maxframe/core/operator/core.py +37 -14
- maxframe/core/operator/fetch.py +5 -18
- maxframe/core/operator/objects.py +0 -20
- maxframe/core/operator/shuffle.py +6 -72
- maxframe/dataframe/__init__.py +1 -0
- maxframe/dataframe/accessors/datetime_/core.py +7 -4
- maxframe/dataframe/accessors/string_/core.py +9 -6
- maxframe/dataframe/arithmetic/core.py +31 -20
- maxframe/dataframe/arithmetic/tests/test_arithmetic.py +6 -0
- maxframe/dataframe/core.py +98 -91
- maxframe/dataframe/datasource/core.py +8 -1
- maxframe/dataframe/datasource/date_range.py +8 -0
- maxframe/dataframe/datasource/from_index.py +9 -5
- maxframe/dataframe/datasource/from_records.py +9 -2
- maxframe/dataframe/datasource/from_tensor.py +32 -21
- maxframe/dataframe/datasource/read_csv.py +8 -2
- maxframe/dataframe/datasource/read_odps_query.py +109 -19
- maxframe/dataframe/datasource/read_odps_table.py +20 -5
- maxframe/dataframe/datasource/read_parquet.py +8 -3
- maxframe/dataframe/datasource/tests/test_datasource.py +80 -1
- maxframe/dataframe/datastore/tests/test_to_odps.py +52 -1
- maxframe/dataframe/datastore/to_csv.py +7 -3
- maxframe/dataframe/datastore/to_odps.py +42 -6
- maxframe/dataframe/extensions/__init__.py +6 -1
- maxframe/dataframe/extensions/apply_chunk.py +96 -136
- maxframe/dataframe/extensions/flatjson.py +3 -2
- maxframe/dataframe/extensions/flatmap.py +15 -7
- maxframe/dataframe/fetch/core.py +12 -1
- maxframe/dataframe/groupby/__init__.py +7 -0
- maxframe/dataframe/groupby/aggregation.py +62 -9
- maxframe/dataframe/groupby/apply.py +50 -74
- maxframe/dataframe/groupby/apply_chunk.py +393 -0
- maxframe/dataframe/groupby/core.py +80 -17
- maxframe/dataframe/groupby/extensions.py +26 -0
- maxframe/dataframe/groupby/fill.py +9 -4
- maxframe/dataframe/groupby/sample.py +7 -7
- maxframe/dataframe/groupby/tests/test_groupby.py +3 -3
- maxframe/dataframe/groupby/transform.py +57 -54
- maxframe/dataframe/indexing/align.py +7 -6
- maxframe/dataframe/indexing/getitem.py +9 -8
- maxframe/dataframe/indexing/iloc.py +28 -23
- maxframe/dataframe/indexing/insert.py +7 -3
- maxframe/dataframe/indexing/loc.py +9 -8
- maxframe/dataframe/indexing/reindex.py +36 -30
- maxframe/dataframe/indexing/rename_axis.py +18 -10
- maxframe/dataframe/indexing/reset_index.py +0 -2
- maxframe/dataframe/indexing/sample.py +13 -9
- maxframe/dataframe/indexing/set_axis.py +9 -6
- maxframe/dataframe/indexing/setitem.py +8 -5
- maxframe/dataframe/indexing/where.py +12 -9
- maxframe/dataframe/merge/__init__.py +0 -1
- maxframe/dataframe/merge/concat.py +10 -31
- maxframe/dataframe/merge/merge.py +2 -24
- maxframe/dataframe/misc/__init__.py +6 -0
- maxframe/dataframe/misc/_duplicate.py +7 -3
- maxframe/dataframe/misc/apply.py +106 -139
- maxframe/dataframe/misc/astype.py +3 -2
- maxframe/dataframe/misc/case_when.py +11 -7
- maxframe/dataframe/misc/cut.py +11 -10
- maxframe/dataframe/misc/describe.py +7 -3
- maxframe/dataframe/misc/drop.py +13 -11
- maxframe/dataframe/misc/eval.py +0 -2
- maxframe/dataframe/misc/get_dummies.py +78 -49
- maxframe/dataframe/misc/isin.py +13 -10
- maxframe/dataframe/misc/map.py +21 -6
- maxframe/dataframe/misc/melt.py +8 -1
- maxframe/dataframe/misc/pivot.py +232 -0
- maxframe/dataframe/misc/pivot_table.py +52 -40
- maxframe/dataframe/misc/rechunk.py +59 -0
- maxframe/dataframe/misc/shift.py +7 -4
- maxframe/dataframe/misc/stack.py +5 -3
- maxframe/dataframe/misc/tests/test_misc.py +167 -1
- maxframe/dataframe/misc/transform.py +63 -65
- maxframe/dataframe/misc/value_counts.py +7 -4
- maxframe/dataframe/missing/dropna.py +16 -7
- maxframe/dataframe/missing/fillna.py +18 -10
- maxframe/dataframe/missing/replace.py +10 -6
- maxframe/dataframe/missing/tests/test_missing.py +2 -2
- maxframe/dataframe/operators.py +1 -27
- maxframe/dataframe/reduction/aggregation.py +128 -3
- maxframe/dataframe/reduction/core.py +20 -6
- maxframe/dataframe/reduction/median.py +1 -1
- maxframe/dataframe/reduction/tests/test_reduction.py +33 -0
- maxframe/dataframe/reduction/unique.py +53 -7
- maxframe/dataframe/statistics/corr.py +9 -6
- maxframe/dataframe/statistics/quantile.py +9 -6
- maxframe/dataframe/tseries/to_datetime.py +6 -4
- maxframe/dataframe/utils.py +219 -31
- maxframe/dataframe/window/rolling.py +7 -4
- maxframe/env.py +1 -0
- maxframe/errors.py +9 -0
- maxframe/extension.py +13 -2
- maxframe/io/objects/core.py +67 -51
- maxframe/io/objects/tensor.py +73 -17
- maxframe/io/objects/tests/test_object_io.py +10 -55
- maxframe/io/odpsio/arrow.py +15 -2
- maxframe/io/odpsio/schema.py +43 -13
- maxframe/io/odpsio/tableio.py +63 -11
- maxframe/io/odpsio/tests/test_arrow.py +1 -2
- maxframe/io/odpsio/tests/test_schema.py +114 -1
- maxframe/io/odpsio/tests/test_tableio.py +42 -0
- maxframe/io/odpsio/tests/test_volumeio.py +21 -58
- maxframe/io/odpsio/volumeio.py +23 -8
- maxframe/learn/__init__.py +2 -2
- maxframe/learn/contrib/__init__.py +2 -2
- maxframe/learn/contrib/graph/connected_components.py +2 -1
- maxframe/learn/contrib/lightgbm/__init__.py +33 -0
- maxframe/learn/contrib/lightgbm/_predict.py +138 -0
- maxframe/learn/contrib/lightgbm/_train.py +163 -0
- maxframe/learn/contrib/lightgbm/callback.py +114 -0
- maxframe/learn/contrib/lightgbm/classifier.py +199 -0
- maxframe/learn/contrib/lightgbm/core.py +372 -0
- maxframe/learn/contrib/lightgbm/dataset.py +153 -0
- maxframe/learn/contrib/lightgbm/regressor.py +29 -0
- maxframe/learn/contrib/lightgbm/tests/__init__.py +13 -0
- maxframe/learn/contrib/lightgbm/tests/test_callback.py +58 -0
- maxframe/learn/contrib/llm/models/dashscope.py +34 -0
- maxframe/learn/contrib/llm/models/managed.py +15 -0
- maxframe/learn/contrib/llm/multi_modal.py +92 -0
- maxframe/learn/contrib/llm/text.py +21 -5
- maxframe/learn/contrib/models.py +38 -9
- maxframe/learn/contrib/utils.py +55 -0
- maxframe/learn/contrib/xgboost/callback.py +86 -0
- maxframe/learn/contrib/xgboost/classifier.py +26 -30
- maxframe/learn/contrib/xgboost/core.py +54 -42
- maxframe/learn/contrib/xgboost/dmatrix.py +19 -12
- maxframe/learn/contrib/xgboost/predict.py +13 -8
- maxframe/learn/contrib/xgboost/regressor.py +28 -27
- maxframe/learn/contrib/xgboost/tests/test_callback.py +41 -0
- maxframe/learn/contrib/xgboost/train.py +59 -16
- maxframe/learn/core.py +252 -0
- maxframe/learn/datasets/__init__.py +20 -0
- maxframe/learn/datasets/samples_generator.py +628 -0
- maxframe/learn/linear_model/__init__.py +15 -0
- maxframe/learn/linear_model/_base.py +163 -0
- maxframe/learn/linear_model/_lin_reg.py +175 -0
- maxframe/learn/metrics/__init__.py +25 -0
- maxframe/learn/metrics/_check_targets.py +95 -0
- maxframe/learn/metrics/_classification.py +1121 -0
- maxframe/learn/metrics/_regression.py +256 -0
- maxframe/learn/model_selection/__init__.py +15 -0
- maxframe/learn/model_selection/_split.py +451 -0
- maxframe/learn/model_selection/tests/__init__.py +13 -0
- maxframe/learn/model_selection/tests/test_split.py +156 -0
- maxframe/learn/preprocessing/__init__.py +16 -0
- maxframe/learn/preprocessing/_data/__init__.py +17 -0
- maxframe/learn/preprocessing/_data/min_max_scaler.py +390 -0
- maxframe/learn/preprocessing/_data/normalize.py +127 -0
- maxframe/learn/preprocessing/_data/standard_scaler.py +503 -0
- maxframe/learn/preprocessing/_data/utils.py +79 -0
- maxframe/learn/preprocessing/_label/__init__.py +16 -0
- maxframe/learn/preprocessing/_label/_label_binarizer.py +599 -0
- maxframe/learn/preprocessing/_label/_label_encoder.py +174 -0
- maxframe/learn/utils/__init__.py +4 -0
- maxframe/learn/utils/_encode.py +314 -0
- maxframe/learn/utils/checks.py +161 -0
- maxframe/learn/utils/core.py +33 -0
- maxframe/learn/utils/extmath.py +176 -0
- maxframe/learn/utils/multiclass.py +292 -0
- maxframe/learn/utils/shuffle.py +114 -0
- maxframe/learn/utils/sparsefuncs.py +87 -0
- maxframe/learn/utils/validation.py +775 -0
- maxframe/lib/__init__.py +0 -2
- maxframe/lib/compat.py +145 -0
- maxframe/lib/filesystem/_oss_lib/glob.py +1 -1
- maxframe/lib/mmh3.cpython-311-darwin.so +0 -0
- maxframe/lib/sparse/__init__.py +10 -15
- maxframe/lib/sparse/array.py +45 -33
- maxframe/lib/sparse/core.py +0 -2
- maxframe/lib/sparse/linalg.py +31 -0
- maxframe/lib/sparse/matrix.py +5 -2
- maxframe/lib/sparse/tests/__init__.py +0 -2
- maxframe/lib/sparse/tests/test_sparse.py +53 -53
- maxframe/lib/sparse/vector.py +0 -2
- maxframe/mixin.py +59 -2
- maxframe/opcodes.py +13 -5
- maxframe/protocol.py +67 -14
- maxframe/remote/core.py +16 -14
- maxframe/remote/run_script.py +6 -3
- maxframe/serialization/__init__.py +2 -0
- maxframe/serialization/core.cpython-311-darwin.so +0 -0
- maxframe/serialization/core.pxd +3 -0
- maxframe/serialization/core.pyi +3 -1
- maxframe/serialization/core.pyx +82 -4
- maxframe/serialization/pandas.py +5 -1
- maxframe/serialization/serializables/core.py +6 -5
- maxframe/serialization/serializables/field.py +2 -2
- maxframe/serialization/serializables/tests/test_field_type.py +3 -5
- maxframe/serialization/tests/test_serial.py +27 -0
- maxframe/session.py +4 -71
- maxframe/sperunner.py +165 -0
- maxframe/tensor/__init__.py +35 -2
- maxframe/tensor/arithmetic/__init__.py +2 -4
- maxframe/tensor/arithmetic/abs.py +0 -2
- maxframe/tensor/arithmetic/absolute.py +0 -2
- maxframe/tensor/arithmetic/add.py +34 -4
- maxframe/tensor/arithmetic/angle.py +0 -2
- maxframe/tensor/arithmetic/arccos.py +1 -4
- maxframe/tensor/arithmetic/arccosh.py +1 -3
- maxframe/tensor/arithmetic/arcsin.py +0 -2
- maxframe/tensor/arithmetic/arcsinh.py +0 -2
- maxframe/tensor/arithmetic/arctan.py +0 -2
- maxframe/tensor/arithmetic/arctan2.py +0 -2
- maxframe/tensor/arithmetic/arctanh.py +0 -2
- maxframe/tensor/arithmetic/around.py +0 -2
- maxframe/tensor/arithmetic/bitand.py +0 -2
- maxframe/tensor/arithmetic/bitor.py +1 -3
- maxframe/tensor/arithmetic/bitxor.py +1 -3
- maxframe/tensor/arithmetic/cbrt.py +0 -2
- maxframe/tensor/arithmetic/ceil.py +0 -2
- maxframe/tensor/arithmetic/clip.py +13 -13
- maxframe/tensor/arithmetic/conj.py +0 -2
- maxframe/tensor/arithmetic/copysign.py +0 -2
- maxframe/tensor/arithmetic/core.py +47 -39
- maxframe/tensor/arithmetic/cos.py +1 -3
- maxframe/tensor/arithmetic/cosh.py +0 -2
- maxframe/tensor/arithmetic/deg2rad.py +0 -2
- maxframe/tensor/arithmetic/degrees.py +0 -2
- maxframe/tensor/arithmetic/divide.py +0 -2
- maxframe/tensor/arithmetic/equal.py +0 -2
- maxframe/tensor/arithmetic/exp.py +1 -3
- maxframe/tensor/arithmetic/exp2.py +0 -2
- maxframe/tensor/arithmetic/expm1.py +0 -2
- maxframe/tensor/arithmetic/fabs.py +0 -2
- maxframe/tensor/arithmetic/fix.py +0 -2
- maxframe/tensor/arithmetic/float_power.py +0 -2
- maxframe/tensor/arithmetic/floor.py +0 -2
- maxframe/tensor/arithmetic/floordiv.py +0 -2
- maxframe/tensor/arithmetic/fmax.py +0 -2
- maxframe/tensor/arithmetic/fmin.py +0 -2
- maxframe/tensor/arithmetic/fmod.py +0 -2
- maxframe/tensor/arithmetic/frexp.py +6 -2
- maxframe/tensor/arithmetic/greater.py +0 -2
- maxframe/tensor/arithmetic/greater_equal.py +0 -2
- maxframe/tensor/arithmetic/hypot.py +0 -2
- maxframe/tensor/arithmetic/i0.py +1 -3
- maxframe/tensor/arithmetic/imag.py +0 -2
- maxframe/tensor/arithmetic/invert.py +1 -3
- maxframe/tensor/arithmetic/isclose.py +0 -2
- maxframe/tensor/arithmetic/iscomplex.py +0 -2
- maxframe/tensor/arithmetic/isfinite.py +1 -3
- maxframe/tensor/arithmetic/isinf.py +0 -2
- maxframe/tensor/arithmetic/isnan.py +0 -2
- maxframe/tensor/arithmetic/isreal.py +0 -2
- maxframe/tensor/arithmetic/ldexp.py +0 -2
- maxframe/tensor/arithmetic/less.py +0 -2
- maxframe/tensor/arithmetic/less_equal.py +0 -2
- maxframe/tensor/arithmetic/log.py +1 -3
- maxframe/tensor/arithmetic/log10.py +1 -3
- maxframe/tensor/arithmetic/log1p.py +1 -3
- maxframe/tensor/arithmetic/log2.py +1 -3
- maxframe/tensor/arithmetic/logaddexp.py +0 -2
- maxframe/tensor/arithmetic/logaddexp2.py +0 -2
- maxframe/tensor/arithmetic/logical_and.py +0 -2
- maxframe/tensor/arithmetic/logical_not.py +1 -3
- maxframe/tensor/arithmetic/logical_or.py +0 -2
- maxframe/tensor/arithmetic/logical_xor.py +0 -2
- maxframe/tensor/arithmetic/lshift.py +0 -2
- maxframe/tensor/arithmetic/maximum.py +0 -2
- maxframe/tensor/arithmetic/minimum.py +0 -2
- maxframe/tensor/arithmetic/mod.py +0 -2
- maxframe/tensor/arithmetic/modf.py +6 -2
- maxframe/tensor/arithmetic/multiply.py +37 -4
- maxframe/tensor/arithmetic/nan_to_num.py +0 -2
- maxframe/tensor/arithmetic/negative.py +0 -2
- maxframe/tensor/arithmetic/nextafter.py +0 -2
- maxframe/tensor/arithmetic/not_equal.py +0 -2
- maxframe/tensor/arithmetic/positive.py +0 -2
- maxframe/tensor/arithmetic/power.py +0 -2
- maxframe/tensor/arithmetic/rad2deg.py +0 -2
- maxframe/tensor/arithmetic/radians.py +0 -2
- maxframe/tensor/arithmetic/real.py +0 -2
- maxframe/tensor/arithmetic/reciprocal.py +5 -3
- maxframe/tensor/arithmetic/rint.py +1 -3
- maxframe/tensor/arithmetic/rshift.py +0 -2
- maxframe/tensor/arithmetic/setimag.py +0 -2
- maxframe/tensor/arithmetic/setreal.py +0 -2
- maxframe/tensor/arithmetic/sign.py +0 -2
- maxframe/tensor/arithmetic/signbit.py +0 -2
- maxframe/tensor/arithmetic/sin.py +0 -2
- maxframe/tensor/arithmetic/sinc.py +1 -3
- maxframe/tensor/arithmetic/sinh.py +0 -2
- maxframe/tensor/arithmetic/spacing.py +0 -2
- maxframe/tensor/arithmetic/sqrt.py +0 -2
- maxframe/tensor/arithmetic/square.py +0 -2
- maxframe/tensor/arithmetic/subtract.py +4 -2
- maxframe/tensor/arithmetic/tan.py +0 -2
- maxframe/tensor/arithmetic/tanh.py +0 -2
- maxframe/tensor/arithmetic/tests/__init__.py +0 -2
- maxframe/tensor/arithmetic/tests/test_arithmetic.py +43 -9
- maxframe/tensor/arithmetic/truediv.py +0 -2
- maxframe/tensor/arithmetic/trunc.py +0 -2
- maxframe/tensor/arithmetic/utils.py +32 -6
- maxframe/tensor/array_utils.py +3 -25
- maxframe/tensor/core.py +6 -6
- maxframe/tensor/datasource/__init__.py +10 -2
- maxframe/tensor/datasource/arange.py +0 -2
- maxframe/tensor/datasource/array.py +3 -22
- maxframe/tensor/datasource/core.py +15 -10
- maxframe/tensor/datasource/diag.py +140 -0
- maxframe/tensor/datasource/diagflat.py +69 -0
- maxframe/tensor/datasource/empty.py +0 -2
- maxframe/tensor/datasource/eye.py +95 -0
- maxframe/tensor/datasource/from_dataframe.py +0 -2
- maxframe/tensor/datasource/from_dense.py +0 -17
- maxframe/tensor/datasource/from_sparse.py +0 -2
- maxframe/tensor/datasource/full.py +0 -2
- maxframe/tensor/datasource/identity.py +54 -0
- maxframe/tensor/datasource/indices.py +115 -0
- maxframe/tensor/datasource/linspace.py +140 -0
- maxframe/tensor/datasource/meshgrid.py +135 -0
- maxframe/tensor/datasource/ones.py +8 -3
- maxframe/tensor/datasource/tests/test_datasource.py +32 -1
- maxframe/tensor/datasource/tri_array.py +107 -0
- maxframe/tensor/datasource/zeros.py +7 -3
- maxframe/tensor/extensions/__init__.py +31 -0
- maxframe/tensor/extensions/accessor.py +25 -0
- maxframe/tensor/extensions/apply_chunk.py +137 -0
- maxframe/tensor/indexing/__init__.py +1 -1
- maxframe/tensor/indexing/choose.py +8 -6
- maxframe/tensor/indexing/compress.py +0 -2
- maxframe/tensor/indexing/extract.py +0 -2
- maxframe/tensor/indexing/fill_diagonal.py +9 -6
- maxframe/tensor/indexing/flatnonzero.py +1 -3
- maxframe/tensor/indexing/getitem.py +10 -43
- maxframe/tensor/indexing/nonzero.py +2 -4
- maxframe/tensor/indexing/setitem.py +19 -9
- maxframe/tensor/indexing/slice.py +6 -3
- maxframe/tensor/indexing/take.py +0 -2
- maxframe/tensor/indexing/tests/__init__.py +0 -2
- maxframe/tensor/indexing/tests/test_indexing.py +0 -2
- maxframe/tensor/indexing/unravel_index.py +6 -6
- maxframe/tensor/lib/__init__.py +16 -0
- maxframe/tensor/lib/index_tricks.py +404 -0
- maxframe/tensor/linalg/__init__.py +36 -0
- maxframe/tensor/linalg/dot.py +145 -0
- maxframe/tensor/linalg/inner.py +36 -0
- maxframe/tensor/linalg/inv.py +83 -0
- maxframe/tensor/linalg/lu.py +115 -0
- maxframe/tensor/linalg/matmul.py +225 -0
- maxframe/tensor/linalg/qr.py +124 -0
- maxframe/tensor/linalg/solve_triangular.py +103 -0
- maxframe/tensor/linalg/svd.py +167 -0
- maxframe/tensor/linalg/tensordot.py +213 -0
- maxframe/tensor/linalg/vdot.py +73 -0
- maxframe/tensor/merge/__init__.py +4 -0
- maxframe/tensor/merge/append.py +74 -0
- maxframe/tensor/merge/column_stack.py +63 -0
- maxframe/tensor/merge/concatenate.py +3 -2
- maxframe/tensor/merge/dstack.py +71 -0
- maxframe/tensor/merge/hstack.py +70 -0
- maxframe/tensor/merge/stack.py +0 -2
- maxframe/tensor/merge/tests/test_merge.py +0 -2
- maxframe/tensor/misc/__init__.py +18 -5
- maxframe/tensor/misc/astype.py +10 -8
- maxframe/tensor/misc/broadcast_to.py +1 -1
- maxframe/tensor/misc/copy.py +64 -0
- maxframe/tensor/misc/diff.py +115 -0
- maxframe/tensor/misc/flatten.py +63 -0
- maxframe/tensor/misc/in1d.py +94 -0
- maxframe/tensor/misc/isin.py +130 -0
- maxframe/tensor/misc/ndim.py +53 -0
- maxframe/tensor/misc/ravel.py +0 -2
- maxframe/tensor/misc/repeat.py +129 -0
- maxframe/tensor/misc/searchsorted.py +147 -0
- maxframe/tensor/misc/setdiff1d.py +58 -0
- maxframe/tensor/misc/squeeze.py +117 -0
- maxframe/tensor/misc/swapaxes.py +113 -0
- maxframe/tensor/misc/tests/test_misc.py +0 -2
- maxframe/tensor/misc/transpose.py +8 -4
- maxframe/tensor/misc/trapezoid.py +123 -0
- maxframe/tensor/misc/unique.py +0 -1
- maxframe/tensor/misc/where.py +10 -8
- maxframe/tensor/operators.py +0 -34
- maxframe/tensor/random/__init__.py +3 -5
- maxframe/tensor/random/binomial.py +0 -2
- maxframe/tensor/random/bytes.py +0 -2
- maxframe/tensor/random/chisquare.py +0 -2
- maxframe/tensor/random/choice.py +9 -8
- maxframe/tensor/random/core.py +20 -5
- maxframe/tensor/random/dirichlet.py +0 -2
- maxframe/tensor/random/exponential.py +0 -2
- maxframe/tensor/random/f.py +2 -4
- maxframe/tensor/random/gamma.py +0 -2
- maxframe/tensor/random/geometric.py +0 -2
- maxframe/tensor/random/gumbel.py +0 -2
- maxframe/tensor/random/hypergeometric.py +0 -2
- maxframe/tensor/random/laplace.py +2 -4
- maxframe/tensor/random/logistic.py +0 -2
- maxframe/tensor/random/lognormal.py +0 -2
- maxframe/tensor/random/logseries.py +0 -2
- maxframe/tensor/random/multinomial.py +0 -2
- maxframe/tensor/random/multivariate_normal.py +0 -2
- maxframe/tensor/random/negative_binomial.py +0 -2
- maxframe/tensor/random/noncentral_chisquare.py +0 -2
- maxframe/tensor/random/noncentral_f.py +1 -3
- maxframe/tensor/random/normal.py +0 -2
- maxframe/tensor/random/pareto.py +0 -2
- maxframe/tensor/random/permutation.py +6 -3
- maxframe/tensor/random/poisson.py +0 -2
- maxframe/tensor/random/power.py +0 -2
- maxframe/tensor/random/rand.py +0 -2
- maxframe/tensor/random/randint.py +0 -2
- maxframe/tensor/random/randn.py +0 -2
- maxframe/tensor/random/random_integers.py +0 -2
- maxframe/tensor/random/random_sample.py +0 -2
- maxframe/tensor/random/rayleigh.py +0 -2
- maxframe/tensor/random/standard_cauchy.py +0 -2
- maxframe/tensor/random/standard_exponential.py +0 -2
- maxframe/tensor/random/standard_gamma.py +0 -2
- maxframe/tensor/random/standard_normal.py +0 -2
- maxframe/tensor/random/standard_t.py +0 -2
- maxframe/tensor/random/tests/__init__.py +0 -2
- maxframe/tensor/random/tests/test_random.py +0 -2
- maxframe/tensor/random/triangular.py +0 -2
- maxframe/tensor/random/uniform.py +0 -2
- maxframe/tensor/random/vonmises.py +0 -2
- maxframe/tensor/random/wald.py +0 -2
- maxframe/tensor/random/weibull.py +0 -2
- maxframe/tensor/random/zipf.py +0 -2
- maxframe/tensor/reduction/__init__.py +0 -2
- maxframe/tensor/reduction/all.py +0 -2
- maxframe/tensor/reduction/allclose.py +0 -2
- maxframe/tensor/reduction/any.py +0 -2
- maxframe/tensor/reduction/argmax.py +1 -3
- maxframe/tensor/reduction/argmin.py +1 -3
- maxframe/tensor/reduction/array_equal.py +0 -2
- maxframe/tensor/reduction/core.py +0 -2
- maxframe/tensor/reduction/count_nonzero.py +0 -2
- maxframe/tensor/reduction/cumprod.py +0 -2
- maxframe/tensor/reduction/cumsum.py +0 -2
- maxframe/tensor/reduction/max.py +0 -2
- maxframe/tensor/reduction/mean.py +0 -2
- maxframe/tensor/reduction/min.py +0 -2
- maxframe/tensor/reduction/nanargmax.py +0 -2
- maxframe/tensor/reduction/nanargmin.py +0 -2
- maxframe/tensor/reduction/nancumprod.py +0 -2
- maxframe/tensor/reduction/nancumsum.py +0 -2
- maxframe/tensor/reduction/nanmax.py +0 -2
- maxframe/tensor/reduction/nanmean.py +0 -2
- maxframe/tensor/reduction/nanmin.py +0 -2
- maxframe/tensor/reduction/nanprod.py +0 -2
- maxframe/tensor/reduction/nanstd.py +0 -2
- maxframe/tensor/reduction/nansum.py +0 -2
- maxframe/tensor/reduction/nanvar.py +0 -2
- maxframe/tensor/reduction/prod.py +0 -2
- maxframe/tensor/reduction/std.py +0 -2
- maxframe/tensor/reduction/sum.py +0 -2
- maxframe/tensor/reduction/tests/test_reduction.py +1 -4
- maxframe/tensor/reduction/var.py +0 -2
- maxframe/tensor/reshape/__init__.py +0 -2
- maxframe/tensor/reshape/reshape.py +6 -5
- maxframe/tensor/reshape/tests/__init__.py +0 -2
- maxframe/tensor/reshape/tests/test_reshape.py +0 -2
- maxframe/tensor/sort/__init__.py +16 -0
- maxframe/tensor/sort/argsort.py +150 -0
- maxframe/tensor/sort/sort.py +295 -0
- maxframe/tensor/special/__init__.py +37 -0
- maxframe/tensor/special/core.py +38 -0
- maxframe/tensor/special/misc.py +142 -0
- maxframe/tensor/special/statistical.py +56 -0
- maxframe/tensor/statistics/__init__.py +5 -0
- maxframe/tensor/statistics/average.py +143 -0
- maxframe/tensor/statistics/bincount.py +133 -0
- maxframe/tensor/statistics/quantile.py +10 -8
- maxframe/tensor/ufunc/__init__.py +0 -2
- maxframe/tensor/ufunc/ufunc.py +0 -2
- maxframe/tensor/utils.py +21 -3
- maxframe/tests/test_protocol.py +3 -3
- maxframe/tests/test_utils.py +210 -1
- maxframe/tests/utils.py +59 -1
- maxframe/udf.py +76 -6
- maxframe/utils.py +418 -17
- {maxframe-1.3.0.dist-info → maxframe-2.0.0.dist-info}/METADATA +5 -1
- maxframe-2.0.0.dist-info/RECORD +939 -0
- {maxframe-1.3.0.dist-info → maxframe-2.0.0.dist-info}/WHEEL +1 -1
- maxframe_client/clients/framedriver.py +19 -3
- maxframe_client/fetcher.py +113 -6
- maxframe_client/session/odps.py +173 -38
- maxframe_client/session/task.py +3 -1
- maxframe_client/tests/test_session.py +41 -5
- maxframe-1.3.0.dist-info/RECORD +0 -705
- {maxframe-1.3.0.dist-info → maxframe-2.0.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,143 @@
|
|
|
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
|
+
import numpy as np
|
|
16
|
+
|
|
17
|
+
from ..datasource import tensor as astensor
|
|
18
|
+
from ..misc.broadcast_to import broadcast_to
|
|
19
|
+
from ..misc.swapaxes import swapaxes
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def average(a, axis=None, weights=None, returned=False):
|
|
23
|
+
"""
|
|
24
|
+
Compute the weighted average along the specified axis.
|
|
25
|
+
|
|
26
|
+
Parameters
|
|
27
|
+
----------
|
|
28
|
+
a : array_like
|
|
29
|
+
Tensor containing data to be averaged. If `a` is not a tensor, a
|
|
30
|
+
conversion is attempted.
|
|
31
|
+
axis : None or int or tuple of ints, optional
|
|
32
|
+
Axis or axes along which to average `a`. The default,
|
|
33
|
+
axis=None, will average over all of the elements of the input tensor.
|
|
34
|
+
If axis is negative it counts from the last to the first axis.
|
|
35
|
+
|
|
36
|
+
If axis is a tuple of ints, averaging is performed on all of the axes
|
|
37
|
+
specified in the tuple instead of a single axis or all the axes as
|
|
38
|
+
before.
|
|
39
|
+
weights : array_like, optional
|
|
40
|
+
A tensor of weights associated with the values in `a`. Each value in
|
|
41
|
+
`a` contributes to the average according to its associated weight.
|
|
42
|
+
The weights tensor can either be 1-D (in which case its length must be
|
|
43
|
+
the size of `a` along the given axis) or of the same shape as `a`.
|
|
44
|
+
If `weights=None`, then all data in `a` are assumed to have a
|
|
45
|
+
weight equal to one.
|
|
46
|
+
returned : bool, optional
|
|
47
|
+
Default is `False`. If `True`, the tuple (`average`, `sum_of_weights`)
|
|
48
|
+
is returned, otherwise only the average is returned.
|
|
49
|
+
If `weights=None`, `sum_of_weights` is equivalent to the number of
|
|
50
|
+
elements over which the average is taken.
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
Returns
|
|
54
|
+
-------
|
|
55
|
+
average, [sum_of_weights] : tensor_type or double
|
|
56
|
+
Return the average along the specified axis. When returned is `True`,
|
|
57
|
+
return a tuple with the average as the first element and the sum
|
|
58
|
+
of the weights as the second element. The return type is `Float`
|
|
59
|
+
if `a` is of integer type, otherwise it is of the same type as `a`.
|
|
60
|
+
`sum_of_weights` is of the same type as `average`.
|
|
61
|
+
|
|
62
|
+
Raises
|
|
63
|
+
------
|
|
64
|
+
ZeroDivisionError
|
|
65
|
+
When all weights along axis are zero. See `numpy.ma.average` for a
|
|
66
|
+
version robust to this type of error.
|
|
67
|
+
TypeError
|
|
68
|
+
When the length of 1D `weights` is not the same as the shape of `a`
|
|
69
|
+
along axis.
|
|
70
|
+
|
|
71
|
+
See Also
|
|
72
|
+
--------
|
|
73
|
+
mean
|
|
74
|
+
|
|
75
|
+
Examples
|
|
76
|
+
--------
|
|
77
|
+
>>> import maxframe.tensor as mt
|
|
78
|
+
|
|
79
|
+
>>> data = list(range(1,5))
|
|
80
|
+
>>> data
|
|
81
|
+
[1, 2, 3, 4]
|
|
82
|
+
>>> mt.average(data).execute()
|
|
83
|
+
2.5
|
|
84
|
+
>>> mt.average(range(1,11), weights=range(10,0,-1)).execute()
|
|
85
|
+
4.0
|
|
86
|
+
|
|
87
|
+
>>> data = mt.arange(6).reshape((3,2))
|
|
88
|
+
>>> data.execute()
|
|
89
|
+
array([[0, 1],
|
|
90
|
+
[2, 3],
|
|
91
|
+
[4, 5]])
|
|
92
|
+
>>> mt.average(data, axis=1, weights=[1./4, 3./4]).execute()
|
|
93
|
+
array([ 0.75, 2.75, 4.75])
|
|
94
|
+
>>> mt.average(data, weights=[1./4, 3./4]).execute()
|
|
95
|
+
Traceback (most recent call last):
|
|
96
|
+
...
|
|
97
|
+
TypeError: Axis must be specified when shapes of a and weights differ.
|
|
98
|
+
|
|
99
|
+
"""
|
|
100
|
+
from ..arithmetic import multiply, truediv
|
|
101
|
+
|
|
102
|
+
a = astensor(a)
|
|
103
|
+
|
|
104
|
+
if weights is None:
|
|
105
|
+
avg = a.mean(axis)
|
|
106
|
+
scl = avg.dtype.type(a.size / avg.size)
|
|
107
|
+
else:
|
|
108
|
+
wgt = astensor(weights)
|
|
109
|
+
|
|
110
|
+
if issubclass(a.dtype.type, (np.integer, np.bool_)):
|
|
111
|
+
result_dtype = np.result_type(a.dtype, wgt.dtype, "f8")
|
|
112
|
+
else:
|
|
113
|
+
result_dtype = np.result_type(a.dtype, wgt.dtype)
|
|
114
|
+
|
|
115
|
+
# sanity checks
|
|
116
|
+
if a.shape != wgt.shape:
|
|
117
|
+
if axis is None:
|
|
118
|
+
raise TypeError(
|
|
119
|
+
"Axis must be specified when shapes of a and weights differ."
|
|
120
|
+
)
|
|
121
|
+
if wgt.ndim != 1:
|
|
122
|
+
raise TypeError(
|
|
123
|
+
"1D weights expected when shapes of a and weights differ."
|
|
124
|
+
)
|
|
125
|
+
if wgt.shape[0] != a.shape[axis]:
|
|
126
|
+
raise ValueError(
|
|
127
|
+
"Length of weights not compatible with specified axis."
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
# setup wgt to broadcast along axis
|
|
131
|
+
wgt = broadcast_to(wgt, (a.ndim - 1) * (1,) + wgt.shape)
|
|
132
|
+
wgt = swapaxes(wgt, -1, axis)
|
|
133
|
+
|
|
134
|
+
scl = wgt.sum(axis=axis, dtype=result_dtype)
|
|
135
|
+
with np.errstate(divide="raise"):
|
|
136
|
+
avg = truediv(multiply(a, wgt, dtype=result_dtype).sum(axis), scl)
|
|
137
|
+
|
|
138
|
+
if returned:
|
|
139
|
+
if scl.shape != avg.shape:
|
|
140
|
+
scl = broadcast_to(scl, avg.shape)
|
|
141
|
+
return avg, scl
|
|
142
|
+
else:
|
|
143
|
+
return avg
|
|
@@ -0,0 +1,133 @@
|
|
|
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 typing import List, Optional
|
|
16
|
+
|
|
17
|
+
import numpy as np
|
|
18
|
+
|
|
19
|
+
from ... import opcodes
|
|
20
|
+
from ...serialization.serializables import Int64Field, ReferenceField
|
|
21
|
+
from ...typing_ import EntityType
|
|
22
|
+
from ..datasource import tensor as astensor
|
|
23
|
+
from ..operators import TensorMapReduceOperator, TensorOperatorMixin
|
|
24
|
+
|
|
25
|
+
_DEFAULT_CHUNK_SIZE_LIMIT = 1e8
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class TensorBinCount(TensorMapReduceOperator, TensorOperatorMixin):
|
|
29
|
+
_op_type_ = opcodes.BINCOUNT
|
|
30
|
+
|
|
31
|
+
weights = ReferenceField("weights", default=None)
|
|
32
|
+
minlength: Optional[int] = Int64Field("minlength", default=0)
|
|
33
|
+
chunk_size_limit: int = Int64Field("chunk_size_limit")
|
|
34
|
+
|
|
35
|
+
chunk_count: Optional[int] = Int64Field("chunk_count")
|
|
36
|
+
tileable_right_bound: Optional[int] = Int64Field("tileable_right_bound")
|
|
37
|
+
|
|
38
|
+
def __call__(self, x, weights=None):
|
|
39
|
+
inputs = [x]
|
|
40
|
+
self.weights = weights
|
|
41
|
+
dtype = np.dtype(np.int_)
|
|
42
|
+
if weights is not None:
|
|
43
|
+
inputs.append(weights)
|
|
44
|
+
dtype = weights.dtype
|
|
45
|
+
return self.new_tensor(inputs, dtype=dtype, shape=(np.nan,))
|
|
46
|
+
|
|
47
|
+
@classmethod
|
|
48
|
+
def _set_inputs(cls, op: "TensorBinCount", inputs: List[EntityType]):
|
|
49
|
+
super()._set_inputs(op, inputs)
|
|
50
|
+
if len(inputs) > 1:
|
|
51
|
+
op.weights = inputs[1]
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def bincount(x, weights=None, minlength=0, chunk_size_limit=None):
|
|
55
|
+
"""
|
|
56
|
+
Count number of occurrences of each value in array of non-negative ints.
|
|
57
|
+
|
|
58
|
+
The number of bins (of size 1) is one larger than the largest value in
|
|
59
|
+
`x`. If `minlength` is specified, there will be at least this number
|
|
60
|
+
of bins in the output array (though it will be longer if necessary,
|
|
61
|
+
depending on the contents of `x`).
|
|
62
|
+
Each bin gives the number of occurrences of its index value in `x`.
|
|
63
|
+
If `weights` is specified the input array is weighted by it, i.e. if a
|
|
64
|
+
value ``n`` is found at position ``i``, ``out[n] += weight[i]`` instead
|
|
65
|
+
of ``out[n] += 1``.
|
|
66
|
+
|
|
67
|
+
Parameters
|
|
68
|
+
----------
|
|
69
|
+
x : tensor or array_like, 1 dimension, nonnegative ints
|
|
70
|
+
Input array.
|
|
71
|
+
weights : tensor or array_like, optional
|
|
72
|
+
Weights, array of the same shape as `x`.
|
|
73
|
+
minlength : int, optional
|
|
74
|
+
A minimum number of bins for the output array.
|
|
75
|
+
|
|
76
|
+
Returns
|
|
77
|
+
-------
|
|
78
|
+
out : tensor of ints
|
|
79
|
+
The result of binning the input array.
|
|
80
|
+
The length of `out` is equal to ``np.amax(x)+1``.
|
|
81
|
+
|
|
82
|
+
Raises
|
|
83
|
+
------
|
|
84
|
+
ValueError
|
|
85
|
+
If the input is not 1-dimensional, or contains elements with negative
|
|
86
|
+
values, or if `minlength` is negative.
|
|
87
|
+
TypeError
|
|
88
|
+
If the type of the input is float or complex.
|
|
89
|
+
|
|
90
|
+
See Also
|
|
91
|
+
--------
|
|
92
|
+
histogram, digitize, unique
|
|
93
|
+
|
|
94
|
+
Examples
|
|
95
|
+
--------
|
|
96
|
+
>>> import maxframe.tensor as mt
|
|
97
|
+
>>> mt.bincount(mt.arange(5)).execute()
|
|
98
|
+
array([1, 1, 1, 1, 1])
|
|
99
|
+
>>> mt.bincount(mt.tensor([0, 1, 1, 3, 2, 1, 7])).execute()
|
|
100
|
+
array([1, 3, 1, 1, 0, 0, 0, 1])
|
|
101
|
+
|
|
102
|
+
The input array needs to be of integer dtype, otherwise a
|
|
103
|
+
TypeError is raised:
|
|
104
|
+
|
|
105
|
+
>>> mt.bincount(mt.arange(5, dtype=float)).execute()
|
|
106
|
+
Traceback (most recent call last):
|
|
107
|
+
....execute()
|
|
108
|
+
TypeError: Cannot cast array data from dtype('float64') to dtype('int64')
|
|
109
|
+
according to the rule 'safe'
|
|
110
|
+
|
|
111
|
+
A possible use of ``bincount`` is to perform sums over
|
|
112
|
+
variable-size chunks of an array, using the ``weights`` keyword.
|
|
113
|
+
|
|
114
|
+
>>> w = mt.array([0.3, 0.5, 0.2, 0.7, 1., -0.6]) # weights
|
|
115
|
+
>>> x = mt.array([0, 1, 1, 2, 2, 2])
|
|
116
|
+
>>> mt.bincount(x, weights=w).execute()
|
|
117
|
+
array([ 0.3, 0.7, 1.1])
|
|
118
|
+
"""
|
|
119
|
+
x = astensor(x)
|
|
120
|
+
weights = astensor(weights) if weights is not None else None
|
|
121
|
+
|
|
122
|
+
if not np.issubdtype(x.dtype, np.int_):
|
|
123
|
+
raise TypeError(f"Cannot cast array data from {x.dtype} to {np.dtype(np.int_)}")
|
|
124
|
+
if x.ndim != 1:
|
|
125
|
+
raise ValueError("'x' must be 1 dimension")
|
|
126
|
+
if minlength < 0:
|
|
127
|
+
raise ValueError("'minlength' must not be negative")
|
|
128
|
+
|
|
129
|
+
chunk_size_limit = (
|
|
130
|
+
chunk_size_limit if chunk_size_limit is not None else _DEFAULT_CHUNK_SIZE_LIMIT
|
|
131
|
+
)
|
|
132
|
+
op = TensorBinCount(minlength=minlength, chunk_size_limit=chunk_size_limit)
|
|
133
|
+
return op(x, weights=weights)
|
|
@@ -13,11 +13,12 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
from collections.abc import Iterable
|
|
16
|
+
from typing import List
|
|
16
17
|
|
|
17
18
|
import numpy as np
|
|
18
19
|
|
|
19
20
|
from ... import opcodes
|
|
20
|
-
from ...core import ENTITY_TYPE
|
|
21
|
+
from ...core import ENTITY_TYPE, EntityData
|
|
21
22
|
from ...serialization.serializables import AnyField, BoolField, KeyField, StringField
|
|
22
23
|
from ..core import TENSOR_TYPE, TensorOrder
|
|
23
24
|
from ..datasource import tensor as astensor
|
|
@@ -57,13 +58,14 @@ class TensorQuantile(TensorOperator, TensorOperatorMixin):
|
|
|
57
58
|
self.q_error_msg = kw.pop("q_error_msg", q_error_msg)
|
|
58
59
|
super().__init__(**kw)
|
|
59
60
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
@classmethod
|
|
62
|
+
def _set_inputs(cls, op: "TensorQuantile", inputs: List[EntityData]):
|
|
63
|
+
super()._set_inputs(op, inputs)
|
|
64
|
+
op.a = op._inputs[0]
|
|
65
|
+
if isinstance(op.q, TENSOR_TYPE):
|
|
66
|
+
op.q = op._inputs[1]
|
|
67
|
+
if isinstance(op.out, TENSOR_TYPE):
|
|
68
|
+
op.out = op._inputs[-1]
|
|
67
69
|
|
|
68
70
|
def __call__(self, a, q=None, out=None):
|
|
69
71
|
shape = [self.q.size] if self.q.ndim > 0 else []
|
maxframe/tensor/ufunc/ufunc.py
CHANGED
maxframe/tensor/utils.py
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
1
|
# Copyright 1999-2025 Alibaba Group Holding Ltd.
|
|
4
2
|
#
|
|
5
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -14,6 +12,7 @@
|
|
|
14
12
|
# See the License for the specific language governing permissions and
|
|
15
13
|
# limitations under the License.
|
|
16
14
|
|
|
15
|
+
import importlib
|
|
17
16
|
import inspect
|
|
18
17
|
import itertools
|
|
19
18
|
import operator
|
|
@@ -669,10 +668,22 @@ def fetch_corner_data(tensor, session=None):
|
|
|
669
668
|
return tensor.fetch(session=session)
|
|
670
669
|
|
|
671
670
|
|
|
672
|
-
def
|
|
671
|
+
def _load_scipy_func(func_name: str):
|
|
672
|
+
try:
|
|
673
|
+
assert func_name.startswith("scipy.")
|
|
674
|
+
mod_name, func_name = func_name.rsplit(".", 1)
|
|
675
|
+
mod = importlib.import_module(mod_name)
|
|
676
|
+
return getattr(mod, func_name)
|
|
677
|
+
except (AttributeError, ImportError):
|
|
678
|
+
return None
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
def implement_scipy(scipy_fun_name):
|
|
673
682
|
import re
|
|
674
683
|
import textwrap
|
|
675
684
|
|
|
685
|
+
scipy_fun = _load_scipy_func(scipy_fun_name)
|
|
686
|
+
|
|
676
687
|
def wrapper(fun):
|
|
677
688
|
if scipy_fun is None:
|
|
678
689
|
return None
|
|
@@ -696,3 +707,10 @@ def implement_scipy(scipy_fun):
|
|
|
696
707
|
return fun
|
|
697
708
|
|
|
698
709
|
return wrapper
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
def infer_scipy_dtype(scipy_fun_name):
|
|
713
|
+
scipy_fun = _load_scipy_func(scipy_fun_name)
|
|
714
|
+
if scipy_fun is None:
|
|
715
|
+
return lambda x: x
|
|
716
|
+
return infer_dtype(scipy_fun)
|
maxframe/tests/test_protocol.py
CHANGED
|
@@ -20,8 +20,8 @@ import pytest
|
|
|
20
20
|
from ..lib import wrapped_pickle
|
|
21
21
|
from ..protocol import (
|
|
22
22
|
DagInfo,
|
|
23
|
-
DagStatus,
|
|
24
23
|
ErrorInfo,
|
|
24
|
+
ExecutionStatus,
|
|
25
25
|
ODPSTableResultInfo,
|
|
26
26
|
ODPSVolumeResultInfo,
|
|
27
27
|
ResultInfo,
|
|
@@ -127,7 +127,7 @@ def test_dag_info_json_serialize():
|
|
|
127
127
|
info = DagInfo(
|
|
128
128
|
session_id="test_session_id",
|
|
129
129
|
dag_id="test_dag_id",
|
|
130
|
-
status=
|
|
130
|
+
status=ExecutionStatus.FAILED,
|
|
131
131
|
progress=0.65,
|
|
132
132
|
tileable_to_result_infos={
|
|
133
133
|
"tileable_key": ODPSTableResultInfo(full_table_name="table_name")
|
|
@@ -153,7 +153,7 @@ def test_session_info_json_serialize():
|
|
|
153
153
|
dag_info = DagInfo(
|
|
154
154
|
session_id="test_session_id",
|
|
155
155
|
dag_id="test_dag_id",
|
|
156
|
-
status=
|
|
156
|
+
status=ExecutionStatus.RUNNING,
|
|
157
157
|
progress=0.65,
|
|
158
158
|
)
|
|
159
159
|
info = SessionInfo(
|
maxframe/tests/test_utils.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
1
|
# Copyright 1999-2025 Alibaba Group Holding Ltd.
|
|
3
2
|
#
|
|
4
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -13,13 +12,16 @@
|
|
|
13
12
|
# See the License for the specific language governing permissions and
|
|
14
13
|
# limitations under the License.
|
|
15
14
|
|
|
15
|
+
import asyncio
|
|
16
16
|
import copy
|
|
17
|
+
import functools
|
|
17
18
|
import os
|
|
18
19
|
import shutil
|
|
19
20
|
import sys
|
|
20
21
|
import tempfile
|
|
21
22
|
import textwrap
|
|
22
23
|
import time
|
|
24
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
23
25
|
from enum import Enum
|
|
24
26
|
from functools import partial
|
|
25
27
|
|
|
@@ -29,6 +31,8 @@ import pyarrow as pa
|
|
|
29
31
|
import pytest
|
|
30
32
|
|
|
31
33
|
from .. import utils
|
|
34
|
+
from ..serialization import PickleContainer
|
|
35
|
+
from ..utils import parse_size_to_megabytes
|
|
32
36
|
|
|
33
37
|
|
|
34
38
|
def test_string_conversion():
|
|
@@ -170,6 +174,9 @@ def test_tokenize():
|
|
|
170
174
|
assert utils.tokenize(partial_f) == utils.tokenize(copy.deepcopy(partial_f))
|
|
171
175
|
assert utils.tokenize(partial_f) != utils.tokenize(partial_f2)
|
|
172
176
|
|
|
177
|
+
container = PickleContainer([b"abcd", b"efgh"])
|
|
178
|
+
assert utils.tokenize(container) == utils.tokenize(copy.deepcopy(container))
|
|
179
|
+
|
|
173
180
|
|
|
174
181
|
def test_lazy_import():
|
|
175
182
|
old_sys_path = sys.path
|
|
@@ -362,3 +369,205 @@ def test_arrow_type_from_string():
|
|
|
362
369
|
_assert_arrow_type_convert(
|
|
363
370
|
pa.struct([("key", pa.string()), ("value", pa.list_(pa.int64()))])
|
|
364
371
|
)
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
@pytest.mark.parametrize("use_async", [False, True])
|
|
375
|
+
async def test_call_with_retry(use_async):
|
|
376
|
+
retry_idx_list = [0]
|
|
377
|
+
|
|
378
|
+
def sync_func(delay=0):
|
|
379
|
+
if delay:
|
|
380
|
+
time.sleep(delay)
|
|
381
|
+
if retry_idx_list[0] < 3:
|
|
382
|
+
retry_idx_list[0] += 1
|
|
383
|
+
raise ValueError
|
|
384
|
+
|
|
385
|
+
async def async_func(delay=0):
|
|
386
|
+
if delay:
|
|
387
|
+
await asyncio.sleep(delay)
|
|
388
|
+
if retry_idx_list[0] < 3:
|
|
389
|
+
retry_idx_list[0] += 1
|
|
390
|
+
raise ValueError
|
|
391
|
+
|
|
392
|
+
func = async_func if use_async else sync_func
|
|
393
|
+
|
|
394
|
+
async def wait_coro(res):
|
|
395
|
+
if asyncio.iscoroutine(res):
|
|
396
|
+
return await res
|
|
397
|
+
return res
|
|
398
|
+
|
|
399
|
+
# test cases for retry times
|
|
400
|
+
with pytest.raises(ValueError):
|
|
401
|
+
retry_idx_list[0] = 0
|
|
402
|
+
await wait_coro(
|
|
403
|
+
utils.call_with_retry(func, retry_times=1, exc_type=(TypeError, ValueError))
|
|
404
|
+
)
|
|
405
|
+
assert retry_idx_list[0] == 2
|
|
406
|
+
|
|
407
|
+
retry_idx_list[0] = 0
|
|
408
|
+
await wait_coro(
|
|
409
|
+
utils.call_with_retry(func, retry_times=3, exc_type=(TypeError, ValueError))
|
|
410
|
+
)
|
|
411
|
+
assert retry_idx_list[0] == 3
|
|
412
|
+
|
|
413
|
+
retry_idx_list[0] = 0
|
|
414
|
+
exc_info = await wait_coro(
|
|
415
|
+
utils.call_with_retry(
|
|
416
|
+
func, retry_times=1, exc_type=(TypeError, ValueError), no_raise=True
|
|
417
|
+
)
|
|
418
|
+
)
|
|
419
|
+
assert isinstance(exc_info[1], ValueError)
|
|
420
|
+
assert retry_idx_list[0] == 2
|
|
421
|
+
|
|
422
|
+
delay_func = functools.partial(func, delay=0.5)
|
|
423
|
+
with pytest.raises(ValueError):
|
|
424
|
+
retry_idx_list[0] = 0
|
|
425
|
+
await wait_coro(
|
|
426
|
+
utils.call_with_retry(delay_func, retry_times=None, retry_timeout=0.7)
|
|
427
|
+
)
|
|
428
|
+
assert retry_idx_list[0] == 2
|
|
429
|
+
|
|
430
|
+
retry_idx_list[0] = 0
|
|
431
|
+
await wait_coro(
|
|
432
|
+
utils.call_with_retry(delay_func, retry_times=None, retry_timeout=2.2)
|
|
433
|
+
)
|
|
434
|
+
assert retry_idx_list[0] == 3
|
|
435
|
+
|
|
436
|
+
retry_idx_list[0] = 0
|
|
437
|
+
exc_info = await wait_coro(
|
|
438
|
+
utils.call_with_retry(
|
|
439
|
+
delay_func, retry_times=None, retry_timeout=0.7, no_raise=True
|
|
440
|
+
)
|
|
441
|
+
)
|
|
442
|
+
assert isinstance(exc_info[1], ValueError)
|
|
443
|
+
assert retry_idx_list[0] == 2
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
def test_debug_to_thread():
|
|
447
|
+
class MixinTestCls(utils.ToThreadMixin):
|
|
448
|
+
async def run_in_coro(self):
|
|
449
|
+
await self.to_thread(time.sleep, 0.5)
|
|
450
|
+
await self.to_thread(functools.partial(time.sleep), 0.5)
|
|
451
|
+
|
|
452
|
+
def thread_body():
|
|
453
|
+
loop = asyncio.new_event_loop()
|
|
454
|
+
loop.set_debug(True)
|
|
455
|
+
asyncio.set_event_loop(loop)
|
|
456
|
+
loop.run_until_complete(MixinTestCls().run_in_coro())
|
|
457
|
+
|
|
458
|
+
tpe = ThreadPoolExecutor(max_workers=1)
|
|
459
|
+
tpe.submit(thread_body).result()
|
|
460
|
+
tpe.shutdown()
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
@pytest.mark.parametrize(
|
|
464
|
+
"val, expected, make_series",
|
|
465
|
+
[
|
|
466
|
+
(int, np.dtype(int), True),
|
|
467
|
+
([int], [np.dtype(int)], False),
|
|
468
|
+
([int], pd.Series([np.dtype(int)]), True),
|
|
469
|
+
(np.dtype("float64"), np.dtype("float64"), True),
|
|
470
|
+
("category", "category", True),
|
|
471
|
+
("string", "string", True),
|
|
472
|
+
(pd.Timestamp, np.dtype("datetime64[ns]"), True),
|
|
473
|
+
(pd.Timedelta, np.dtype("timedelta64[ns]"), True),
|
|
474
|
+
({"col": float}, {"col": np.dtype(float)}, False),
|
|
475
|
+
({"col": float}, pd.Series({"col": np.dtype(float)}), True),
|
|
476
|
+
(
|
|
477
|
+
pd.Series([float], index=["col"]),
|
|
478
|
+
pd.Series([np.dtype(float)], index=["col"]),
|
|
479
|
+
True,
|
|
480
|
+
),
|
|
481
|
+
],
|
|
482
|
+
)
|
|
483
|
+
def test_make_dtypes(val, expected, make_series):
|
|
484
|
+
result = utils.make_dtypes(val, make_series=make_series)
|
|
485
|
+
if isinstance(expected, pd.Series):
|
|
486
|
+
pd.testing.assert_series_equal(result, expected)
|
|
487
|
+
else:
|
|
488
|
+
assert result == expected
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
# Define conversion constants
|
|
492
|
+
BYTES_PER_KIB = 1024
|
|
493
|
+
BYTES_PER_MIB = 1024**2
|
|
494
|
+
BYTES_PER_GIB = 1024**3
|
|
495
|
+
BYTES_PER_TIB = 1024**4
|
|
496
|
+
|
|
497
|
+
BYTES_PER_KB = 1000
|
|
498
|
+
BYTES_PER_MB = 1000**2
|
|
499
|
+
BYTES_PER_GB = 1000**3
|
|
500
|
+
BYTES_PER_TB = 1000**4
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
# Test numeric values with default units
|
|
504
|
+
@pytest.mark.parametrize("value", [0, 1, 4, 5, 0.01, 0.1, 0.5, 1.5])
|
|
505
|
+
@pytest.mark.parametrize(
|
|
506
|
+
"default_unit", ["KiB", "MiB", "GiB", "TiB", "KB", "MB", "GB", "TB"]
|
|
507
|
+
)
|
|
508
|
+
def test_numeric_inputs_with_default_units(value, default_unit):
|
|
509
|
+
"""Test numeric inputs with various default units"""
|
|
510
|
+
# Define unit conversions to MiB for reusability
|
|
511
|
+
unit_to_mib_factor = {
|
|
512
|
+
"KiB": BYTES_PER_KIB / BYTES_PER_MIB,
|
|
513
|
+
"MiB": 1,
|
|
514
|
+
"GiB": BYTES_PER_GIB / BYTES_PER_MIB,
|
|
515
|
+
"TiB": BYTES_PER_TIB / BYTES_PER_MIB,
|
|
516
|
+
"KB": BYTES_PER_KB / BYTES_PER_MIB,
|
|
517
|
+
"MB": BYTES_PER_MB / BYTES_PER_MIB,
|
|
518
|
+
"GB": BYTES_PER_GB / BYTES_PER_MIB,
|
|
519
|
+
"TB": BYTES_PER_TB / BYTES_PER_MIB,
|
|
520
|
+
}
|
|
521
|
+
expected = value * unit_to_mib_factor[default_unit]
|
|
522
|
+
result = parse_size_to_megabytes(value, default_number_unit=default_unit)
|
|
523
|
+
assert pytest.approx(result) == expected
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
@pytest.mark.parametrize(
|
|
527
|
+
"input_string, expected",
|
|
528
|
+
[
|
|
529
|
+
# Basic binary units
|
|
530
|
+
("1KiB", BYTES_PER_KIB / BYTES_PER_MIB),
|
|
531
|
+
("5miB", 5),
|
|
532
|
+
("2giB", 2 * BYTES_PER_GIB / BYTES_PER_MIB),
|
|
533
|
+
("0.1TiB", 0.1 * BYTES_PER_TIB / BYTES_PER_MIB),
|
|
534
|
+
# Basic decimal units
|
|
535
|
+
("1KB", BYTES_PER_KB / BYTES_PER_MIB),
|
|
536
|
+
("10MB", 10 * BYTES_PER_MB / BYTES_PER_MIB),
|
|
537
|
+
("0.5GB", 0.5 * BYTES_PER_GB / BYTES_PER_MIB),
|
|
538
|
+
("0.01TB", 0.01 * BYTES_PER_TB / BYTES_PER_MIB),
|
|
539
|
+
# Abbreviated forms
|
|
540
|
+
("1K", BYTES_PER_KB / BYTES_PER_MIB),
|
|
541
|
+
("10M", 10 * BYTES_PER_MB / BYTES_PER_MIB),
|
|
542
|
+
("0.5g", 0.5 * BYTES_PER_GB / BYTES_PER_MIB),
|
|
543
|
+
("0.01T", 0.01 * BYTES_PER_TB / BYTES_PER_MIB),
|
|
544
|
+
# With spaces
|
|
545
|
+
("1 kiB", BYTES_PER_KIB / BYTES_PER_MIB),
|
|
546
|
+
("10 MB", 10 * BYTES_PER_MB / BYTES_PER_MIB),
|
|
547
|
+
(" 0.5 GiB ", 0.5 * BYTES_PER_GIB / BYTES_PER_MIB),
|
|
548
|
+
("0.01 TB", 0.01 * BYTES_PER_TB / BYTES_PER_MIB),
|
|
549
|
+
],
|
|
550
|
+
)
|
|
551
|
+
def test_string_values_with_units(input_string, expected):
|
|
552
|
+
"""Test various string inputs with different units"""
|
|
553
|
+
result = parse_size_to_megabytes(input_string, default_number_unit="GiB")
|
|
554
|
+
assert pytest.approx(result) == expected
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
@pytest.mark.parametrize(
|
|
558
|
+
"invalid_input, default_unit",
|
|
559
|
+
[
|
|
560
|
+
("invalid", "GiB"), # Non-numeric input
|
|
561
|
+
("1.2.3GiB", "GiB"), # Invalid number format
|
|
562
|
+
("1ZiB", "GiB"), # Invalid unit
|
|
563
|
+
("GiB", "GiB"), # Missing number
|
|
564
|
+
("1G1B", "GiB"), # Invalid format
|
|
565
|
+
(5, None), # Numeric input with default_number_unit as None
|
|
566
|
+
("5", None), # String numeric input with default_number_unit as None
|
|
567
|
+
("5", "Gibb"), # String numeric input with bad default_number_unit
|
|
568
|
+
],
|
|
569
|
+
)
|
|
570
|
+
def test_parse_size_to_mega_bytes_invalid_inputs(invalid_input, default_unit):
|
|
571
|
+
"""Test invalid inputs that should raise ValueError"""
|
|
572
|
+
with pytest.raises(ValueError): # Catch ValueError
|
|
573
|
+
parse_size_to_megabytes(invalid_input, default_number_unit=default_unit)
|