maxframe 0.1.0b3__cp39-cp39-macosx_10_9_x86_64.whl → 0.1.0b4__cp39-cp39-macosx_10_9_x86_64.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.

Binary file
maxframe/config/config.py CHANGED
@@ -358,6 +358,9 @@ default_options.register_option(
358
358
  default_options.register_option(
359
359
  "show_progress", "auto", validator=any_validator(is_bool, is_string)
360
360
  )
361
+ default_options.register_option(
362
+ "dag.settings", value=dict(), validator=is_dict, remote=True
363
+ )
361
364
 
362
365
  ################
363
366
  # SPE Settings #
@@ -57,6 +57,11 @@ try:
57
57
  except ImportError: # pragma: no cover
58
58
  pass
59
59
 
60
+ try:
61
+ from . import _internal
62
+ except ImportError: # pragma: no cover
63
+ pass
64
+
60
65
  del (
61
66
  arithmetic,
62
67
  datasource,
@@ -960,7 +960,9 @@ class BaseSeriesData(HasShapeTileableData, _ToPandasMixin):
960
960
  buf = StringIO()
961
961
  max_rows = pd.get_option("display.max_rows")
962
962
  corner_max_rows = (
963
- max_rows if self.shape[0] <= max_rows else corner_data.shape[0] - 1
963
+ max_rows
964
+ if self.shape[0] <= max_rows or corner_data.shape[0] == 0
965
+ else corner_data.shape[0] - 1
964
966
  ) # make sure max_rows < corner_data
965
967
 
966
968
  with pd.option_context("display.max_rows", corner_max_rows):
@@ -1605,7 +1607,7 @@ class DataFrameData(_BatchedFetcher, BaseDataFrameData):
1605
1607
  buf = StringIO()
1606
1608
  max_rows = pd.get_option("display.max_rows")
1607
1609
 
1608
- if self.shape[0] <= max_rows:
1610
+ if self.shape[0] <= max_rows or corner_data.shape[0] == 0:
1609
1611
  buf.write(repr(corner_data) if representation else str(corner_data))
1610
1612
  else:
1611
1613
  # remember we cannot directly call repr(df),
@@ -263,7 +263,9 @@ def read_odps_query(
263
263
  result: DataFrame
264
264
  DataFrame read from MaxCompute (ODPS) table
265
265
  """
266
- odps_entry = odps_entry or ODPS.from_environments()
266
+ odps_entry = odps_entry or ODPS.from_global() or ODPS.from_environments()
267
+ if odps_entry is None:
268
+ raise ValueError("Missing odps_entry parameter")
267
269
  inst = odps_entry.execute_sql(f"EXPLAIN {query}")
268
270
  explain_str = list(inst.get_task_results().values())[0]
269
271
 
@@ -164,6 +164,8 @@ def read_odps_table(
164
164
  DataFrame read from MaxCompute (ODPS) table
165
165
  """
166
166
  odps_entry = odps_entry or ODPS.from_global() or ODPS.from_environments()
167
+ if odps_entry is None:
168
+ raise ValueError("Missing odps_entry parameter")
167
169
  if isinstance(table_name, Table):
168
170
  table = table_name
169
171
  else:
@@ -0,0 +1,19 @@
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
+ from ..operators import DataFrameOperator, DataFrameOperatorMixin
16
+
17
+
18
+ class DataFrameDataStore(DataFrameOperator, DataFrameOperatorMixin):
19
+ pass
@@ -23,11 +23,11 @@ from ...serialization.serializables import (
23
23
  ListField,
24
24
  StringField,
25
25
  )
26
- from ..operators import DataFrameOperator, DataFrameOperatorMixin
27
26
  from ..utils import parse_index
27
+ from .core import DataFrameDataStore
28
28
 
29
29
 
30
- class DataFrameToCSV(DataFrameOperator, DataFrameOperatorMixin):
30
+ class DataFrameToCSV(DataFrameDataStore):
31
31
  _op_type_ = opcodes.TO_CSV
32
32
 
33
33
  input = KeyField("input")
@@ -32,13 +32,13 @@ from ...serialization.serializables import (
32
32
  )
33
33
  from ...typing_ import TileableType
34
34
  from ..core import DataFrame # noqa: F401
35
- from ..operators import DataFrameOperator, DataFrameOperatorMixin
36
35
  from ..utils import parse_index
36
+ from .core import DataFrameDataStore
37
37
 
38
38
  logger = logging.getLogger(__name__)
39
39
 
40
40
 
41
- class DataFrameToODPSTable(DataFrameOperator, DataFrameOperatorMixin):
41
+ class DataFrameToODPSTable(DataFrameDataStore):
42
42
  _op_type_ = opcodes.TO_ODPS_TABLE
43
43
 
44
44
  dtypes = SeriesField("dtypes")
@@ -107,7 +107,6 @@ def df_reset_index(
107
107
  inplace=False,
108
108
  col_level=0,
109
109
  col_fill="",
110
- incremental_index=False,
111
110
  ):
112
111
  """
113
112
  Reset the index, or a level of it.
@@ -133,12 +132,6 @@ def df_reset_index(
133
132
  col_fill : object, default ''
134
133
  If the columns have multiple levels, determines how the other
135
134
  levels are named. If None then the index name is repeated.
136
- incremental_index: bool, default False
137
- Ensure RangeIndex incremental, when output DataFrame has multiple chunks,
138
- ensuring index incremental costs more computation,
139
- so by default, each chunk will have index which starts from 0,
140
- setting incremental_index=True,reset_index will guarantee that
141
- output DataFrame's index is from 0 to n - 1.
142
135
 
143
136
  Returns
144
137
  -------
@@ -264,7 +257,6 @@ def df_reset_index(
264
257
  drop=drop,
265
258
  col_level=col_level,
266
259
  col_fill=col_fill,
267
- incremental_index=incremental_index,
268
260
  output_types=[OutputType.dataframe],
269
261
  )
270
262
  ret = op(df)
@@ -280,7 +272,6 @@ def series_reset_index(
280
272
  drop=False,
281
273
  name=no_default,
282
274
  inplace=False,
283
- incremental_index=False,
284
275
  ):
285
276
  """
286
277
  Generate a new DataFrame or Series with the index reset.
@@ -303,12 +294,6 @@ def series_reset_index(
303
294
  when `drop` is True.
304
295
  inplace : bool, default False
305
296
  Modify the Series in place (do not create a new object).
306
- incremental_index: bool, default False
307
- Ensure RangeIndex incremental, when output Series has multiple chunks,
308
- ensuring index incremental costs more computation,
309
- so by default, each chunk will have index which starts from 0,
310
- setting incremental_index=True,reset_index will guarantee that
311
- output Series's index is from 0 to n - 1.
312
297
 
313
298
  Returns
314
299
  -------
@@ -406,8 +391,7 @@ def series_reset_index(
406
391
  level=level,
407
392
  drop=drop,
408
393
  name=name,
409
- incremental_index=incremental_index,
410
- output_types=[OutputType.series],
394
+ output_types=[OutputType.series if drop else OutputType.dataframe],
411
395
  )
412
396
  ret = op(series)
413
397
  if not inplace:
Binary file
maxframe/odpsio/arrow.py CHANGED
@@ -65,14 +65,19 @@ def arrow_to_pandas(
65
65
  raise ValueError(f"Does not support meta type {table_meta.type!r}")
66
66
 
67
67
 
68
- def pandas_to_arrow(df: Any, nthreads=1) -> Tuple[ArrowTableType, DataFrameTableMeta]:
69
- table_meta = build_dataframe_table_meta(df)
68
+ def pandas_to_arrow(
69
+ df: Any, nthreads=1, ignore_index=False
70
+ ) -> Tuple[ArrowTableType, DataFrameTableMeta]:
71
+ table_meta = build_dataframe_table_meta(df, ignore_index)
70
72
  df = df.copy() if callable(getattr(df, "copy", None)) else df
71
73
  if table_meta.type in (OutputType.dataframe, OutputType.series):
72
74
  if table_meta.type == OutputType.series:
73
75
  df = df.to_frame("_data" if df.name is None else df.name)
74
76
  df.columns = pd.Index(table_meta.table_column_names)
75
- df = df.rename_axis(table_meta.table_index_column_names).reset_index()
77
+ if not ignore_index:
78
+ df = df.rename_axis(table_meta.table_index_column_names).reset_index()
79
+ elif ignore_index:
80
+ df = pd.DataFrame([], columns=[])
76
81
  elif table_meta.type == OutputType.index:
77
82
  names = [f"_idx_{idx}" for idx in range(len(df.names))]
78
83
  df = df.to_frame(name=names[0] if len(names) == 1 else names)
maxframe/odpsio/schema.py CHANGED
@@ -175,7 +175,9 @@ def _scalar_as_index(df_obj: Any) -> pd.Index:
175
175
 
176
176
 
177
177
  def pandas_to_odps_schema(
178
- df_obj: Any, unknown_as_string: bool = False
178
+ df_obj: Any,
179
+ unknown_as_string: bool = False,
180
+ ignore_index=False,
179
181
  ) -> Tuple[odps_types.OdpsSchema, DataFrameTableMeta]:
180
182
  from .. import dataframe as md
181
183
  from .arrow import pandas_to_arrow
@@ -209,7 +211,7 @@ def pandas_to_odps_schema(
209
211
  else:
210
212
  empty_df_obj = df_obj
211
213
 
212
- arrow_data, table_meta = pandas_to_arrow(empty_df_obj)
214
+ arrow_data, table_meta = pandas_to_arrow(empty_df_obj, ignore_index=ignore_index)
213
215
  return (
214
216
  arrow_schema_to_odps_schema(
215
217
  arrow_data.schema, unknown_as_string=unknown_as_string
@@ -268,7 +270,9 @@ def build_table_column_name(
268
270
  return col_name
269
271
 
270
272
 
271
- def build_dataframe_table_meta(df_obj: Any) -> DataFrameTableMeta:
273
+ def build_dataframe_table_meta(
274
+ df_obj: Any, ignore_index: bool = False
275
+ ) -> DataFrameTableMeta:
272
276
  from .. import dataframe as md
273
277
 
274
278
  col_to_count = defaultdict(lambda: 0)
@@ -285,6 +289,8 @@ def build_dataframe_table_meta(df_obj: Any) -> DataFrameTableMeta:
285
289
  else: # pragma: no cover
286
290
  raise TypeError(f"Cannot accept type {type(df_obj)}")
287
291
 
292
+ assert not ignore_index or obj_type in (OutputType.dataframe, OutputType.series)
293
+
288
294
  if obj_type == OutputType.scalar:
289
295
  pd_dtypes = pd.Series([])
290
296
  column_index_names = []
@@ -340,12 +346,19 @@ def build_dataframe_table_meta(df_obj: Any) -> DataFrameTableMeta:
340
346
  else:
341
347
  index_dtypes = pd.Series([pd_index_val.dtype], index=pd_index_val.names)
342
348
 
349
+ if ignore_index:
350
+ table_index_column_names = []
351
+ pd_index_dtypes = pd.Series([], index=[])
352
+ else:
353
+ table_index_column_names = [f"_idx_{i}" for i in range(len(index_obj.names))]
354
+ pd_index_dtypes = index_dtypes
355
+
343
356
  return DataFrameTableMeta(
344
357
  table_name=table_name,
345
358
  type=obj_type,
346
359
  table_column_names=final_sql_columns,
347
- table_index_column_names=[f"_idx_{i}" for i in range(len(index_obj.names))],
360
+ table_index_column_names=table_index_column_names,
348
361
  pd_column_dtypes=pd_dtypes,
349
362
  pd_column_level_names=column_index_names,
350
- pd_index_dtypes=index_dtypes,
363
+ pd_index_dtypes=pd_index_dtypes,
351
364
  )
@@ -61,6 +61,16 @@ def test_pandas_to_odps_schema_dataframe(wrap_obj):
61
61
  assert meta.pd_column_level_names == [None]
62
62
  assert meta.pd_index_level_names == [None]
63
63
 
64
+ test_df = _wrap_maxframe_obj(data, wrap=wrap_obj)
65
+ schema, meta = pandas_to_odps_schema(test_df, ignore_index=True)
66
+ assert [c.name for c in schema.columns] == list(test_df.dtypes.index.str.lower())
67
+ assert [c.type.name for c in schema.columns] == ["double"] * len(test_df.columns)
68
+ assert meta.type == OutputType.dataframe
69
+ assert meta.table_column_names == list(test_df.dtypes.index.str.lower())
70
+ assert meta.table_index_column_names == []
71
+ assert meta.pd_column_level_names == [None]
72
+ assert meta.pd_index_level_names == []
73
+
64
74
  data.columns = pd.MultiIndex.from_tuples(
65
75
  [("A", "A"), ("A", "B"), ("A", "C"), ("B", "A"), ("B", "B")], names=["c1", "c2"]
66
76
  )
@@ -99,6 +109,15 @@ def test_pandas_to_odps_schema_series(wrap_obj):
99
109
  assert meta.pd_column_level_names == [None]
100
110
  assert meta.pd_index_level_names == [None]
101
111
 
112
+ schema, meta = pandas_to_odps_schema(test_s, ignore_index=True)
113
+ assert [c.name for c in schema.columns] == ["_data"]
114
+ assert [c.type.name for c in schema.columns] == ["double"]
115
+ assert meta.type == OutputType.series
116
+ assert meta.table_column_names == ["_data"]
117
+ assert meta.table_index_column_names == []
118
+ assert meta.pd_column_level_names == [None]
119
+ assert meta.pd_index_level_names == []
120
+
102
121
  data.index = pd.MultiIndex.from_arrays(
103
122
  [np.random.choice(list("ABC"), 100), np.random.randint(0, 10, 100)],
104
123
  names=["c1", "c2"],
@@ -130,6 +149,9 @@ def test_pandas_to_odps_schema_index(wrap_obj):
130
149
  assert meta.pd_column_level_names == []
131
150
  assert meta.pd_index_level_names == [None]
132
151
 
152
+ with pytest.raises(AssertionError):
153
+ pandas_to_odps_schema(test_idx, unknown_as_string=True, ignore_index=True)
154
+
133
155
  data = pd.MultiIndex.from_arrays(
134
156
  [np.random.choice(list("ABC"), 100), np.random.randint(0, 10, 100)],
135
157
  names=["c1", "c2"],
@@ -159,6 +181,9 @@ def test_pandas_to_odps_schema_scalar(wrap_obj):
159
181
  assert meta.pd_column_level_names == []
160
182
  assert meta.pd_index_level_names == [None]
161
183
 
184
+ with pytest.raises(AssertionError):
185
+ pandas_to_odps_schema(test_scalar, unknown_as_string=True, ignore_index=True)
186
+
162
187
 
163
188
  def test_odps_arrow_schema_conversion():
164
189
  odps_schema = odps_types.OdpsSchema(
maxframe/opcodes.py CHANGED
@@ -564,6 +564,11 @@ CHOLESKY_FUSE = 999988
564
564
  # MaxFrame-dedicated functions
565
565
  DATAFRAME_RESHUFFLE = 10001
566
566
 
567
+ # MaxFrame internal operators
568
+ DATAFRAME_PROJECTION_SAME_INDEX_MERGE = 100001
569
+ GROUPBY_AGGR_SAME_INDEX_MERGE = 100002
570
+ DATAFRAME_ILOC_GET_AND_RENAME_ITEM = 100003
571
+
567
572
  # fetches
568
573
  FETCH_SHUFFLE = 999998
569
574
  FETCH = 999999
maxframe/session.py CHANGED
@@ -1211,7 +1211,7 @@ def new_session(
1211
1211
  # load third party extensions.
1212
1212
  ensure_isolation_created(kwargs)
1213
1213
 
1214
- odps_entry = odps_entry or ODPS.from_environments()
1214
+ odps_entry = odps_entry or ODPS.from_global() or ODPS.from_environments()
1215
1215
  if address is None:
1216
1216
  from maxframe_client.session.consts import ODPS_SESSION_INSECURE_SCHEME
1217
1217
 
@@ -1255,7 +1255,9 @@ def get_default_or_create(**kwargs):
1255
1255
  if session is None:
1256
1256
  # no session attached, try to create one
1257
1257
  warnings.warn(warning_msg)
1258
- session = new_session(ODPS.from_environments(), **kwargs)
1258
+ session = new_session(
1259
+ ODPS.from_global() or ODPS.from_environments(), **kwargs
1260
+ )
1259
1261
  session.as_default()
1260
1262
  if isinstance(session, IsolatedAsyncSession):
1261
1263
  session = SyncSession.from_isolated_session(session)
maxframe/utils.py CHANGED
@@ -381,6 +381,11 @@ def build_temp_table_name(session_id: str, tileable_key: str) -> str:
381
381
  return f"tmp_mf_{session_id}_{tileable_key}"
382
382
 
383
383
 
384
+ def build_temp_intermediate_table_name(session_id: str, tileable_key: str) -> str:
385
+ temp_table = build_temp_table_name(session_id, tileable_key)
386
+ return f"{temp_table}_intermediate"
387
+
388
+
384
389
  def build_session_volume_name(session_id: str) -> str:
385
390
  return f"mf_vol_{session_id}"
386
391
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: maxframe
3
- Version: 0.1.0b3
3
+ Version: 0.1.0b4
4
4
  Summary: MaxFrame operator-based data analyze framework
5
5
  Requires-Dist: numpy >=1.19.0
6
6
  Requires-Dist: pandas >=1.0.0
@@ -1,42 +1,42 @@
1
- maxframe-0.1.0b3.dist-info/RECORD,,
2
- maxframe-0.1.0b3.dist-info/WHEEL,sha256=wEvD9HODgqXG21zAA07x3Gh0qpNEHOQ7qzjMqXvopac,109
3
- maxframe-0.1.0b3.dist-info/top_level.txt,sha256=64x-fc2q59c_vXwNUkehyjF1vb8JWqFSdYmUqIFqoTM,31
4
- maxframe-0.1.0b3.dist-info/METADATA,sha256=056zhE5bxFHo_1CAOnpi1A2Ov1JI8hg435HsygF02lA,3043
1
+ maxframe-0.1.0b4.dist-info/RECORD,,
2
+ maxframe-0.1.0b4.dist-info/WHEEL,sha256=wEvD9HODgqXG21zAA07x3Gh0qpNEHOQ7qzjMqXvopac,109
3
+ maxframe-0.1.0b4.dist-info/top_level.txt,sha256=64x-fc2q59c_vXwNUkehyjF1vb8JWqFSdYmUqIFqoTM,31
4
+ maxframe-0.1.0b4.dist-info/METADATA,sha256=M5MjCW0gBbtdN7bOgXnAyVv3__iRHgIGuqRb_qHAHi4,3043
5
5
  maxframe_client/conftest.py,sha256=7cwy2sFy5snEaxvtMvxfYFUnG6WtYC_9XxVrwJxOpcU,643
6
6
  maxframe_client/__init__.py,sha256=3b-z0oFVVwtIzVFBxOb9pw7gz4IhTSh4FiHtVgnxS4Q,724
7
7
  maxframe_client/fetcher.py,sha256=Ys_qu2qtniXuj9YSfeHvevdrAAEgm8k4YjyoZusdVmg,6813
8
8
  maxframe_client/clients/__init__.py,sha256=FEFOVLi3o2GpZoedTtLYvbie0eQBehJIjtCrWca2ZHw,596
9
9
  maxframe_client/clients/spe.py,sha256=ArZMNQ7olicI4O1JO7CyRP7-hb60DF71ZKCTO0N39uE,3593
10
10
  maxframe_client/clients/framedriver.py,sha256=Rn09529D2qBTgNGc0oCY0l7b3FgzT87TqS1nujGQaHw,4463
11
- maxframe_client/tests/test_session.py,sha256=75mxU5UTWjb1loQLo9BAkg7BzKuj4vYX49j4vP1-8fA,6307
11
+ maxframe_client/tests/test_session.py,sha256=ZaiQTsnn-qr3VzdyuSei05AeM3FYhVpXQizg50mcSRc,6902
12
12
  maxframe_client/tests/__init__.py,sha256=FEFOVLi3o2GpZoedTtLYvbie0eQBehJIjtCrWca2ZHw,596
13
13
  maxframe_client/tests/test_fetcher.py,sha256=q7kYCznM6WSxx9TCbHrxs7Zy1L2a5zu9D-Pi1XNgQzg,3516
14
14
  maxframe_client/session/task.py,sha256=z5j8qtBM6cs_lZrvfy4Ji3F3sVOhPOCr5r1RsNe7rN4,11102
15
15
  maxframe_client/session/graph.py,sha256=nwILNOIVaIf4E3xWffTAAlRsKRYU_zGW3oVO10du8Xw,4351
16
16
  maxframe_client/session/__init__.py,sha256=KPqhSlAJiuUz8TC-z5o7mHDVXzLSqWwrZ33zNni7piY,832
17
17
  maxframe_client/session/consts.py,sha256=R37BxDF3kgCy0qmDdwLaH5jB7mb7SzfYV6g9yHBKAwk,1344
18
- maxframe_client/session/odps.py,sha256=uuPk5rc1OpFk9PNFU1R6r4HQXOHAOU7ZVvbcdGk_N_s,16248
18
+ maxframe_client/session/odps.py,sha256=4O4lpoEICC7PwDu6koGZ1XOXuCt_zSblF6xtPARl7n8,16328
19
19
  maxframe_client/session/tests/test_task.py,sha256=lDdw3gToaM3xSaRXEmHUoAo2h0id7t4v_VvpdKxQAao,3279
20
20
  maxframe_client/session/tests/__init__.py,sha256=FEFOVLi3o2GpZoedTtLYvbie0eQBehJIjtCrWca2ZHw,596
21
21
  maxframe/_utils.pyx,sha256=I4kmfhNr-xXK2ak22dr4Vwahzn-JmTaYctbL3y9_UBQ,17017
22
22
  maxframe/conftest.py,sha256=ZzwKhGp7LAVpzQYJkniwIUQqIegcaDQAhyzDyU2qld4,4264
23
- maxframe/opcodes.py,sha256=L1_GGenexNnD4dk1ueelgpAebHCC-cY7d--1QPhw8l4,9984
23
+ maxframe/opcodes.py,sha256=FE9MUlENCKaO2gVIaSweF5Rsti6nKfYoD-vSRkoPlgM,10145
24
24
  maxframe/env.py,sha256=_K499f7giN7Iu9f39iI9p_naaEDoJ0rx8dInbzqFOVI,1402
25
25
  maxframe/mixin.py,sha256=HBAeWYGb7N6ZIgkA-YpkKiSY1GetcEVNTuMb0ieznBs,3524
26
26
  maxframe/protocol.py,sha256=LjjE6iw0ZVx82tBMbff4izkGuiJxRG0MTOaPYYpRL10,14190
27
- maxframe/session.py,sha256=TspAq0EUhi-7VQb1kAuQyjhpX8vMYqgdk4vzbGCkJcY,35344
27
+ maxframe/session.py,sha256=y1XSn2G5PAQenuAkz2hb54CuWStbb_S8IFdMcJiNyoQ,35418
28
28
  maxframe/__init__.py,sha256=YGnga-nYEppPoDZoZ5s64PZ0RYLaWtcYtmYSLTjKUBE,976
29
- maxframe/utils.py,sha256=BrMJLO0-iPKABkNztXWpqiQWHoe-X75HGiCJr5aeles,33914
29
+ maxframe/utils.py,sha256=0cAfRm_M5vfSGzaLgLqEu8M75nYK9BOd_lQowejpdHY,34104
30
30
  maxframe/extension.py,sha256=4IzF9sPyaRoAzLud0iDLooOgcyq4QunXH0ki3q9Hn8I,2374
31
31
  maxframe/errors.py,sha256=nQZoLGdLJz-Uf9c2vUvQl08QMvRqtkBOhKfdPYRZA4o,690
32
32
  maxframe/udf.py,sha256=tWOMTkNqGWw3ZpNC9wEU0GGNSBV8sV7E-Ye80DI28eg,2241
33
- maxframe/_utils.cpython-39-darwin.so,sha256=-0bVNg7VTmXNgn_QM6AG8QBuR80wx2tSP8OuzLUiQPs,472632
33
+ maxframe/_utils.cpython-39-darwin.so,sha256=clk1nu3odUr-0DHv5Yr6gYGONMfH0ASYm22lGE9ZDUo,472632
34
34
  maxframe/typing_.py,sha256=fzHETru3IOZAJwU9I7n_ib3wHuQRJ9XFVmAk7WpqkMo,1096
35
35
  maxframe/codegen.py,sha256=pSiGHoEo9YajFPHbFHvi7fGkiJmAQdBCe0mMXNOG6-U,15846
36
36
  maxframe/_utils.pxd,sha256=AhJ4vA_UqZqPshi5nvIZq1xgr80fhIVQ9dm5-UdkYJ8,1154
37
37
  maxframe/dataframe/arrays.py,sha256=RWzimUcrds5CsIlPausfJAkLUjcktBSSXwdXyUNKEtU,28752
38
- maxframe/dataframe/__init__.py,sha256=tpbt4OgW4hoU_1OsQu1WSxbpZD4YPXW_oT4xOxNPNqE,2112
39
- maxframe/dataframe/core.py,sha256=mJ5I_qBP8HDAzlwPnkj8RN4EyBHC8d5unbe2LC6HKXg,73641
38
+ maxframe/dataframe/__init__.py,sha256=h4SQPQQBpVPxTNGP5Rtx5uO7RI8gO7_FpXjeh_k9PN8,2195
39
+ maxframe/dataframe/core.py,sha256=aNkexKwBuaQv28R0HYTLXcD64U4nEcBsBfLfGCFSSGs,73731
40
40
  maxframe/dataframe/initializer.py,sha256=4BpZJB8bbyFnABUYWBrk_qzzrogEsWgFuU21Ma9IsjY,10264
41
41
  maxframe/dataframe/utils.py,sha256=qWRo51rcMTlo4mvZ8ZZq1zIF9CiAgU1qRtoCAaYrR34,44111
42
42
  maxframe/dataframe/operators.py,sha256=T7Ik1shfoyrMZ1x0wHXG26bsod1_YjMGQgGAFNpH6k0,7871
@@ -83,10 +83,10 @@ maxframe/dataframe/datasource/from_index.py,sha256=2061zsQn-BhyHTT0X9tE0JK8vLxQU
83
83
  maxframe/dataframe/datasource/dataframe.py,sha256=LxAKF4gBIHhnJQPuaAUdIEyMAq7HTfiEeNVls5n4I4A,2023
84
84
  maxframe/dataframe/datasource/series.py,sha256=QcYiBNcR8jjH6vdO6l6H9F46KHmlBqVCTI2tv9eyZ9w,1909
85
85
  maxframe/dataframe/datasource/__init__.py,sha256=C8EKsHTJi-1jvJUKIpZtMtsK-ZID3dtxL1voXnaltTs,640
86
- maxframe/dataframe/datasource/read_odps_query.py,sha256=nj8l38S0iVAXgNXgzDFERO-HNp6lJ1GahImwDpEzXXw,9821
86
+ maxframe/dataframe/datasource/read_odps_query.py,sha256=PkDtM1lG2odWcgjtKOdr5A95rqlkiFUKQy03v5-4pqU,9927
87
87
  maxframe/dataframe/datasource/core.py,sha256=ozFmDgw1og7nK9_jU-u3tLEq9pNbitN-8w8XWdbKkJ0,2687
88
88
  maxframe/dataframe/datasource/date_range.py,sha256=CDGpxDyjLwnb66j-MIiiTfXGXHGh5MLhEmj6x2riIlU,17244
89
- maxframe/dataframe/datasource/read_odps_table.py,sha256=VCqWxJswcjujVoUNXb2kbTkOZroMkFCg5n272Yn7ME4,9045
89
+ maxframe/dataframe/datasource/read_odps_table.py,sha256=u3TNBlSMvQzKMQXFincqWKcUu8a4jeXX_RW3gctPXF4,9129
90
90
  maxframe/dataframe/datasource/read_parquet.py,sha256=9auOcy8snTxCOohgXZCUXfT_O39irdkBngZH5svgx0E,14531
91
91
  maxframe/dataframe/datasource/from_tensor.py,sha256=4viuN5SLLye7Xeb8kouOpm-osoQ2yEovWTDNPQuW8gE,14727
92
92
  maxframe/dataframe/datasource/from_records.py,sha256=WBYouYyg7m_8NJdN-yUWSfJlIpm6DVP3IMfLXZFugyI,3442
@@ -138,8 +138,9 @@ maxframe/dataframe/groupby/apply.py,sha256=gZVHN8nMXoy7BEHTBAVLQKtGicQ_jB3dsny8j
138
138
  maxframe/dataframe/groupby/tests/__init__.py,sha256=FEFOVLi3o2GpZoedTtLYvbie0eQBehJIjtCrWca2ZHw,596
139
139
  maxframe/dataframe/groupby/tests/test_groupby.py,sha256=VsHDG-UaZUXlZ1l498y44ecfzJJ9D2oY4QmPCjS6wBs,12142
140
140
  maxframe/dataframe/datastore/__init__.py,sha256=Ujd4ix4UJ7Zq-sV2pXTRDvZkKUvtt8sr-FfiUoi6Kh4,784
141
- maxframe/dataframe/datastore/to_csv.py,sha256=VUTocKlrDVyOs3Cvve9NwHtiKNJ2sQTnYnG11ML3kxE,7799
142
- maxframe/dataframe/datastore/to_odps.py,sha256=h8WOZ759Q9aHw8HdCAws0T979_SYXuSP5NcUgT2cTPw,5614
141
+ maxframe/dataframe/datastore/core.py,sha256=hLGhqYxX73tq9sOFxMyYBRMawTnsVQqluW5FcE3YHfE,743
142
+ maxframe/dataframe/datastore/to_csv.py,sha256=xVfpEsicD5A5uXLSdCN08K8uGyWB4QxnRcAbgBVUzbs,7747
143
+ maxframe/dataframe/datastore/to_odps.py,sha256=wZzD3yc6YQAGYVwEzYY-qxscn8Sj9I43lR70tFHe3m0,5562
143
144
  maxframe/dataframe/fetch/__init__.py,sha256=E3VjxLRKjtr-D__K-c0aRETvBG7CQRG1iEtH0Qghq0s,653
144
145
  maxframe/dataframe/fetch/core.py,sha256=z61_orBtOIrKFpFdJTNqyPhOw5ZCGe6QkXnDrGdMy6U,3338
145
146
  maxframe/dataframe/reduction/max.py,sha256=CqaueIN3cuF7vlE2rt2MAcXAD3Syd_R8W2dzcFhTmV0,1660
@@ -233,7 +234,7 @@ maxframe/dataframe/arithmetic/radians.py,sha256=pSq9S0KlV0Xx0vGSdxdol3348dSyYuxG
233
234
  maxframe/dataframe/arithmetic/sin.py,sha256=zgWoijVpASlkZ7cnZZxKSSHUiLqQ0pKUAIOHEfCBubc,915
234
235
  maxframe/dataframe/arithmetic/tests/__init__.py,sha256=FEFOVLi3o2GpZoedTtLYvbie0eQBehJIjtCrWca2ZHw,596
235
236
  maxframe/dataframe/arithmetic/tests/test_arithmetic.py,sha256=Zm0hwTo_NqFAa3iDmYF2Q10-884d8ltOsby2WjcioBA,24372
236
- maxframe/dataframe/indexing/reset_index.py,sha256=pdLv7YwyY-lMGg4qegGmRzu-MLNjg--xESZ4jeDcl1I,13992
237
+ maxframe/dataframe/indexing/reset_index.py,sha256=uzGszHfkhwZgZtEaygy5UPrvHPNPXgWZaTOXdNxGBT8,13122
237
238
  maxframe/dataframe/indexing/iat.py,sha256=ANURJ8qn_UitgM01gDPeaQOlSBxbk0pmN4Yr-iPRXM8,1127
238
239
  maxframe/dataframe/indexing/loc.py,sha256=ZmiK3a2f-krkXFvNLSlzRRa6GWGiAAXk_3mWZC_MqdQ,14845
239
240
  maxframe/dataframe/indexing/align.py,sha256=BdrfIrf6A7v8W0GIuv1mdx87CzR15ARnqIH_aWUjWqY,12089
@@ -273,7 +274,7 @@ maxframe/core/entity/objects.py,sha256=RMHLTGbIHZNxxX59lAuQydAKcR32qKleIYUqdElGS
273
274
  maxframe/core/entity/fuse.py,sha256=47U6MHRzA2ZvUi-kJb7b3mC_gN07x3yebBgX2Jj7VZo,2277
274
275
  maxframe/core/entity/chunks.py,sha256=yNSLCWOpA_Z6aGr6ZI32dIJf3xPdRBWbvdsl8sTM3BE,2134
275
276
  maxframe/core/graph/__init__.py,sha256=rnsXwW0ouh1f7SVtq73-PzLE-MBM6Op_0l6J7b7wGRE,821
276
- maxframe/core/graph/core.cpython-39-darwin.so,sha256=JyoianB3w6hvC1hEN5m-sSMxSzMgVuHZEqlxiCqkPWY,361136
277
+ maxframe/core/graph/core.cpython-39-darwin.so,sha256=x0X9hBLzRMexkwWkUgCWPaKpCtAZSk8usunXor2vlsU,361136
277
278
  maxframe/core/graph/entity.py,sha256=56gjXyDXN-TTPm3AQOxuRVQbb_fguKFDL_Xm7i95XEk,5559
278
279
  maxframe/core/graph/core.pyx,sha256=ZJPx_MTOBMaX-6mns6tAiu-wrIBvRAKN44YAGTypJ1Y,15887
279
280
  maxframe/core/graph/tests/__init__.py,sha256=FEFOVLi3o2GpZoedTtLYvbie0eQBehJIjtCrWca2ZHw,596
@@ -294,7 +295,7 @@ maxframe/core/operator/fuse.py,sha256=0RGemF99gQCwV4aEk-K6T5KAGToO-487dFk8LyYDIZ
294
295
  maxframe/core/operator/base.py,sha256=nxuSKjbBzDrItM9PGmFo8RLwParazu525jMLWj0kXkM,15251
295
296
  maxframe/core/operator/tests/test_core.py,sha256=57aICnc5VLqdVK7icAORTWC81bSjBxeeVWIJcha9J_0,1691
296
297
  maxframe/core/operator/tests/__init__.py,sha256=FEFOVLi3o2GpZoedTtLYvbie0eQBehJIjtCrWca2ZHw,596
297
- maxframe/config/config.py,sha256=3lQj99eMGg9MBW1gMJAdGFD88UEcdZf71sHgAHXASAk,13045
298
+ maxframe/config/config.py,sha256=zWw0kzlkNbsKY5_oee2e5mdWqC_qrxor42SRkA-hSz0,13145
298
299
  maxframe/config/validators.py,sha256=2m9MrkjDUFiU4PPaWIw8tjwMaOy8AYmuJFqVnnY8IMY,1615
299
300
  maxframe/config/__init__.py,sha256=g5lN3nP2HTAXa6ExGxU1NwU1M9ulYPmAcsV-gU7nIW8,656
300
301
  maxframe/config/tests/__init__.py,sha256=FEFOVLi3o2GpZoedTtLYvbie0eQBehJIjtCrWca2ZHw,596
@@ -307,7 +308,7 @@ maxframe/serialization/arrow.py,sha256=VnGxNLU9UV_cUPTze43bEFCIbYLAOZnp2pAwVJbAI
307
308
  maxframe/serialization/__init__.py,sha256=9eSnoDww1uw2DAXEBBTB2atJQHzd-38XVxrCkoaypxA,921
308
309
  maxframe/serialization/maxframe_objects.py,sha256=R9WEjbHL0Kr56OGkYDU9fcGi7gII6fGlXhi6IyihTsM,1365
309
310
  maxframe/serialization/numpy.py,sha256=8_GSo45l_eNoMn4NAGEb9NLXY_9i4tf9KK4EzG0mKpA,3213
310
- maxframe/serialization/core.cpython-39-darwin.so,sha256=73Gy4lTdTxSp10w4Wn2HlIDyWtS5NSIxM72I9PUSiUs,695248
311
+ maxframe/serialization/core.cpython-39-darwin.so,sha256=Yk95GGq96MQvY8nK32haE24gtgsVl-o-sdM-sViW3ko,695248
311
312
  maxframe/serialization/scipy.py,sha256=hP0fAW0di9UgJrGtANB2S8hLDbFBtR8p5NDqAMt5rDI,2427
312
313
  maxframe/serialization/core.pyx,sha256=AATN47RdBTq2zg7--3xX2VHyAZSvoAuYRt7B7gEgKPE,33984
313
314
  maxframe/serialization/tests/test_serial.py,sha256=Wj_I6CBQMaOtE8WtqdUaBoU8FhBOihht6SfeHOJV-zU,12511
@@ -320,13 +321,13 @@ maxframe/serialization/serializables/tests/test_field_type.py,sha256=T3ebXbUkKve
320
321
  maxframe/serialization/serializables/tests/__init__.py,sha256=FEFOVLi3o2GpZoedTtLYvbie0eQBehJIjtCrWca2ZHw,596
321
322
  maxframe/serialization/serializables/tests/test_serializable.py,sha256=nwdN7B2xnI_Bh-s90TyjPvyFFVWOE9JVBqm4bdwYZ6o,8243
322
323
  maxframe/odpsio/tableio.py,sha256=QjjcNxb8h0OXvif3xDarsjq-52aqsWdPezpSn46__g0,9360
323
- maxframe/odpsio/arrow.py,sha256=S9wgULzuUeqQNhBuEXp2yaAA5E9EZM0PTteqM345tRA,3645
324
+ maxframe/odpsio/arrow.py,sha256=jNbfb36TDzpMjloDyXkwCfGDiCe-8z3IGMNlF_s1fIs,3783
324
325
  maxframe/odpsio/__init__.py,sha256=HcxZsE4hRwbhtE-ZXhDWZMmQlv-2dOTvQq2NajhGEo4,799
325
326
  maxframe/odpsio/volumeio.py,sha256=b2SQqusgrtkJJ6uMjnFv5s56XjchF8F4lLTTSHynRMc,3743
326
- maxframe/odpsio/schema.py,sha256=WsJ0bi1-78g6adyPKQFqFJRH3YPXMqGl_qmOe5z7me4,11717
327
+ maxframe/odpsio/schema.py,sha256=aXvK_1BSwttuUyROyIa_HNHohLZBp7LrW9VXzHPGXyY,12115
327
328
  maxframe/odpsio/tests/test_tableio.py,sha256=5nKq8I8Pzrfl89BjIIGyrvqPRiXdejTcYCtd-R2vTAo,4653
328
329
  maxframe/odpsio/tests/__init__.py,sha256=FEFOVLi3o2GpZoedTtLYvbie0eQBehJIjtCrWca2ZHw,596
329
- maxframe/odpsio/tests/test_schema.py,sha256=yss1ly55ErYse95XMFq2s_GWL8UnwZga5RyNIhtcx70,10572
330
+ maxframe/odpsio/tests/test_schema.py,sha256=pfBGHdgnCOcvuvEe66WCZDt_ijG2jaoA_lCKC9-ejYo,11796
330
331
  maxframe/odpsio/tests/test_arrow.py,sha256=SQ9EmI9_VOOC8u6Rg6nh3IPC2fPbLvJ9HwtpMNDRhL8,3106
331
332
  maxframe/odpsio/tests/test_volumeio.py,sha256=UEqFANuPKyFtlIh2JNi-LoixH52bxsgHdxu3himnEvs,3022
332
333
  maxframe/tests/test_utils.py,sha256=xaAoURr5NOJUTY0XVa2H8qOStcEH5UQSXItkatHFxFE,11977
@@ -336,7 +337,7 @@ maxframe/tests/utils.py,sha256=wJtSFXt3BD4i5zdO4JBQk_kNAxrtyGLro0jodCA4xuY,4568
336
337
  maxframe/tests/test_codegen.py,sha256=GMrnpSb2eyB_nmuv8-_p47Kw877ElKS3BP52SpqZNIQ,2208
337
338
  maxframe/lib/wrapped_pickle.py,sha256=xJa0wI-GsBZFKQpVnlh_hZBlQ2u1D8VO2aBIW7VOdP4,3810
338
339
  maxframe/lib/version.py,sha256=yQ6HkDOvU9X1rpI49auh-qku2g7gIiztgEH6v1urOrk,18321
339
- maxframe/lib/mmh3.cpython-39-darwin.so,sha256=h0knHWqb6EkQMYeDR3S4njVKljScfp8z4PjRh84-odI,38064
340
+ maxframe/lib/mmh3.cpython-39-darwin.so,sha256=k1LxN-M5KCoPVF9uLkXcmQDNjieQSQ7DTrmA7wO5fvU,38064
340
341
  maxframe/lib/compression.py,sha256=k9DSrl_dNBsn5azLjBdL5B4WZ6eNvmCrdMbcF1G7JSc,1442
341
342
  maxframe/lib/__init__.py,sha256=CzfbLNqqm1yR1i6fDwCd4h1ptuKVDbURFVCb0ra7QNc,642
342
343
  maxframe/lib/functools_compat.py,sha256=PMSkct9GIbzq-aBwTnggrOLNfLh4xQnYTIFMPblzCUA,2616
@@ -115,7 +115,7 @@ class MaxFrameSession(ToThreadMixin, IsolatedAsyncSession):
115
115
  ):
116
116
  super().__init__(address, session_id)
117
117
  self.timeout = timeout
118
- self._odps_entry = odps_entry or ODPS.from_environments()
118
+ self._odps_entry = odps_entry or ODPS.from_global() or ODPS.from_environments()
119
119
  self._tileable_to_infos = weakref.WeakKeyDictionary()
120
120
 
121
121
  self._caller = self._create_caller(odps_entry, address, **kwargs)
@@ -147,15 +147,16 @@ class MaxFrameSession(ToThreadMixin, IsolatedAsyncSession):
147
147
  data = t.op.get_data()
148
148
  batch_size = options.session.upload_batch_size
149
149
 
150
- halo_client = HaloTableIO(self._odps_entry)
151
- with halo_client.open_writer(table_obj.full_table_name) as writer:
152
- for batch_start in range(0, len(data), batch_size):
153
- if isinstance(data, pd.Index):
154
- batch = data[batch_start : batch_start + batch_size]
155
- else:
156
- batch = data.iloc[batch_start : batch_start + batch_size]
157
- arrow_batch, _ = pandas_to_arrow(batch)
158
- writer.write(arrow_batch)
150
+ if len(data):
151
+ halo_client = HaloTableIO(self._odps_entry)
152
+ with halo_client.open_writer(table_obj.full_table_name) as writer:
153
+ for batch_start in range(0, len(data), batch_size):
154
+ if isinstance(data, pd.Index):
155
+ batch = data[batch_start : batch_start + batch_size]
156
+ else:
157
+ batch = data.iloc[batch_start : batch_start + batch_size]
158
+ arrow_batch, _ = pandas_to_arrow(batch)
159
+ writer.write(arrow_batch)
159
160
 
160
161
  read_tileable = read_odps_table(
161
162
  table_obj.full_table_name,
@@ -28,6 +28,7 @@ from maxframe.lib.aio import stop_isolation
28
28
  from maxframe.protocol import ResultInfo
29
29
  from maxframe.serialization import RemoteException
30
30
  from maxframe.session import new_session
31
+ from maxframe.tests.utils import tn
31
32
  from maxframe.utils import build_temp_table_name
32
33
  from maxframe_framedriver.app.tests.test_framedriver_webapp import ( # noqa: F401
33
34
  framedriver_app,
@@ -115,6 +116,26 @@ def test_simple_run_dataframe(start_mock_session):
115
116
  assert not odps_entry.exist_table(build_temp_table_name(start_mock_session, key))
116
117
 
117
118
 
119
+ def test_run_empty_table(start_mock_session):
120
+ odps_entry = ODPS.from_environments()
121
+
122
+ table_name = tn("test_session_empty_table")
123
+ odps_entry.delete_table(table_name, if_exists=True)
124
+ empty_table = odps_entry.create_table(
125
+ table_name, "_idx_0 bigint, a double, b double", lifecycle=1
126
+ )
127
+ df = md.read_odps_table(table_name, index_col="_idx_0")
128
+ df["d"] = df["a"] + df["b"]
129
+
130
+ executed = df.execute()
131
+ assert "Index: []" in str(executed)
132
+
133
+ fetched = executed.fetch()
134
+ assert 0 == len(fetched)
135
+
136
+ empty_table.drop()
137
+
138
+
118
139
  def test_run_dataframe_with_pd_source(start_mock_session):
119
140
  odps_entry = ODPS.from_environments()
120
141