2727import bigframes .core .identifiers as ids
2828import bigframes .core .indexes as indexes
2929import bigframes .core .scalar as scalars
30+ import bigframes .core .utils as bf_utils
3031import bigframes .dtypes
3132import bigframes .operations as ops
3233import bigframes .operations .aggregations as agg_ops
@@ -69,40 +70,21 @@ def __init__(
6970 raise ValueError (
7071 f"Series constructor only supports copy=True. { constants .FEEDBACK_LINK } "
7172 )
73+
7274 if isinstance (data , blocks .Block ):
73- # Constructing from block is for internal use only - shouldn't use parameters, block encompasses all state
74- assert len (data .value_columns ) == 1
75- assert len (data .column_labels ) == 1
76- assert index is None
77- assert name is None
78- assert dtype is None
7975 block = data
80-
81- # interpret these cases as both index and data
82- elif isinstance (data , bigframes .pandas .Series ) or pd .api .types .is_dict_like (
83- data
84- ): # includes pd.Series
85- if isinstance (data , bigframes .pandas .Series ):
86- data = data .copy ()
87- if name is not None :
88- data .name = name
89- if dtype is not None :
90- bf_dtype = bigframes .dtypes .bigframes_type (dtype )
91- data = data .astype (bf_dtype )
92- else : # local dict-like data
93- data = read_pandas_func (pd .Series (data , name = name , dtype = dtype )) # type: ignore
94- data_block = data ._block
95- if index is not None :
96- # reindex
97- bf_index = indexes .Index (index , session = session )
98- idx_block = bf_index ._block
99- idx_cols = idx_block .value_columns
100- block_idx , _ = idx_block .join (data_block , how = "left" )
101- data_block = block_idx .with_index_labels (bf_index .names )
102- block = data_block
103-
104- # list-like data that will get default index
105- elif isinstance (data , indexes .Index ) or pd .api .types .is_list_like (data ):
76+ elif isinstance (data , SeriesMethods ):
77+ block = data ._get_block ()
78+ # special case where data is local scalar, but index is bigframes index (maybe very big)
79+ elif (
80+ not bf_utils .is_list_like (data ) and not isinstance (data , indexes .Index )
81+ ) and isinstance (index , indexes .Index ):
82+ block = index ._block
83+ block , _ = block .create_constant (data )
84+ block = block .with_column_labels ([None ])
85+ # prevents no-op reindex later
86+ index = None
87+ elif isinstance (data , indexes .Index ) or isinstance (index , indexes .Index ):
10688 data = indexes .Index (data , dtype = dtype , name = name , session = session )
10789 # set to none as it has already been applied, avoid re-cast later
10890 if data .nlevels != 1 :
@@ -111,8 +93,7 @@ def __init__(
11193 data_block = data ._block .reset_index (drop = False ).with_column_labels (
11294 data .names
11395 )
114- if index is not None :
115- # Align by offset
96+ if index is not None : # Align data and index by offset
11697 bf_index = indexes .Index (index , session = session )
11798 idx_block = bf_index ._block .reset_index (
11899 drop = False
@@ -121,19 +102,32 @@ def __init__(
121102 data_block , (l_mapping , _ ) = idx_block .join (data_block , how = "left" )
122103 data_block = data_block .set_index ([l_mapping [col ] for col in idx_cols ])
123104 data_block = data_block .with_index_labels (bf_index .names )
105+ # prevents no-op reindex later
106+ index = None
124107 block = data_block
125108
126- else : # Scalar case
127- if index is not None :
128- bf_index = indexes .Index (index , session = session )
129- else :
130- bf_index = indexes .Index (
131- [] if (data is None ) else [0 ],
132- session = session ,
133- dtype = bigframes .dtypes .INT_DTYPE ,
134- )
135- block , _ = bf_index ._block .create_constant (data , dtype )
136- block = block .with_column_labels ([name ])
109+ if block :
110+ assert len (block .value_columns ) == 1
111+ assert len (block .column_labels ) == 1
112+ if index is not None : # reindexing operation
113+ bf_index = indexes .Index (index )
114+ idx_block = bf_index ._block
115+ idx_cols = idx_block .index_columns
116+ block , _ = idx_block .join (block , how = "left" )
117+ block = block .with_index_labels (bf_index .names )
118+ if name :
119+ block = block .with_column_labels ([name ])
120+ if dtype :
121+ bf_dtype = bigframes .dtypes .bigframes_type (dtype )
122+ block = block .multi_apply_unary_op (ops .AsTypeOp (to_type = bf_dtype ))
123+ else :
124+ pd_series = pd .Series (
125+ data = data ,
126+ index = index , # type:ignore
127+ dtype = dtype , # type:ignore
128+ name = name ,
129+ )
130+ block = read_pandas_func (pd_series )._get_block () # type:ignore
137131
138132 assert block is not None
139133 self ._block : blocks .Block = block
0 commit comments