24
24
25
25
import bigframes .constants as constants
26
26
import bigframes .core as core
27
+ import bigframes .core .block_transforms as block_ops
27
28
import bigframes .core .blocks as blocks
28
29
import bigframes .core .joins as joins
30
+ import bigframes .core .ordering as order
29
31
import bigframes .core .utils as utils
30
32
import bigframes .dtypes
31
33
import bigframes .dtypes as bf_dtypes
@@ -149,6 +151,27 @@ def has_duplicates(self) -> bool:
149
151
def _block (self ) -> blocks .Block :
150
152
return self ._data ._get_block ()
151
153
154
+ @property
155
+ def T (self ) -> Index :
156
+ return self .transpose ()
157
+
158
+ def transpose (self ) -> Index :
159
+ return self
160
+
161
+ def sort_values (self , * , ascending : bool = True , na_position : str = "last" ):
162
+ if na_position not in ["first" , "last" ]:
163
+ raise ValueError ("Param na_position must be one of 'first' or 'last'" )
164
+ direction = (
165
+ order .OrderingDirection .ASC if ascending else order .OrderingDirection .DESC
166
+ )
167
+ na_last = na_position == "last"
168
+ index_columns = self ._block .index_columns
169
+ ordering = [
170
+ order .OrderingColumnReference (column , direction = direction , na_last = na_last )
171
+ for column in index_columns
172
+ ]
173
+ return Index ._from_block (self ._block .order_by (ordering ))
174
+
152
175
def astype (
153
176
self ,
154
177
dtype : Union [bigframes .dtypes .DtypeString , bigframes .dtypes .Dtype ],
@@ -176,6 +199,57 @@ def max(self) -> typing.Any:
176
199
def min (self ) -> typing .Any :
177
200
return self ._apply_aggregation (agg_ops .min_op )
178
201
202
+ def argmax (self ) -> int :
203
+ block , row_nums = self ._block .promote_offsets ()
204
+ block = block .order_by (
205
+ [
206
+ * [
207
+ order .OrderingColumnReference (
208
+ col , direction = order .OrderingDirection .DESC
209
+ )
210
+ for col in self ._block .index_columns
211
+ ],
212
+ order .OrderingColumnReference (row_nums ),
213
+ ]
214
+ )
215
+ import bigframes .series as series
216
+
217
+ return typing .cast (int , series .Series (block .select_column (row_nums )).iloc [0 ])
218
+
219
+ def argmin (self ) -> int :
220
+ block , row_nums = self ._block .promote_offsets ()
221
+ block = block .order_by (
222
+ [
223
+ * [
224
+ order .OrderingColumnReference (col )
225
+ for col in self ._block .index_columns
226
+ ],
227
+ order .OrderingColumnReference (row_nums ),
228
+ ]
229
+ )
230
+ import bigframes .series as series
231
+
232
+ return typing .cast (int , series .Series (block .select_column (row_nums )).iloc [0 ])
233
+
234
+ def value_counts (
235
+ self ,
236
+ normalize : bool = False ,
237
+ sort : bool = True ,
238
+ ascending : bool = False ,
239
+ * ,
240
+ dropna : bool = True ,
241
+ ):
242
+ block = block_ops .value_counts (
243
+ self ._block ,
244
+ self ._block .index_columns ,
245
+ normalize = normalize ,
246
+ ascending = ascending ,
247
+ dropna = dropna ,
248
+ )
249
+ import bigframes .series as series
250
+
251
+ return series .Series (block )
252
+
179
253
def fillna (self , value = None ) -> Index :
180
254
if self .nlevels > 1 :
181
255
raise TypeError ("Multiindex does not support 'fillna'" )
@@ -185,10 +259,7 @@ def rename(self, name: Union[str, Sequence[str]]) -> Index:
185
259
names = [name ] if isinstance (name , str ) else list (name )
186
260
if len (names ) != self .nlevels :
187
261
raise ValueError ("'name' must be same length as levels" )
188
-
189
- import bigframes .dataframe as df
190
-
191
- return Index (df .DataFrame (self ._block .with_index_labels (names )))
262
+ return Index ._from_block (self ._block .with_index_labels (names ))
192
263
193
264
def drop (
194
265
self ,
@@ -210,9 +281,28 @@ def drop(
210
281
)
211
282
block = block .filter (condition_id , keep_null = True )
212
283
block = block .drop_columns ([condition_id ])
213
- import bigframes .dataframe as df
284
+ return Index ._from_block (block )
285
+
286
+ def dropna (self , how : str = "any" ) -> Index :
287
+ if how not in ("any" , "all" ):
288
+ raise ValueError ("'how' must be one of 'any', 'all'" )
289
+ result = block_ops .dropna (self ._block , self ._block .index_columns , how = how ) # type: ignore
290
+ return Index ._from_block (result )
291
+
292
+ def drop_duplicates (self , * , keep : str = "first" ) -> Index :
293
+ block = block_ops .drop_duplicates (self ._block , self ._block .index_columns , keep )
294
+ return Index ._from_block (block )
295
+
296
+ def isin (self , values ) -> Index :
297
+ if not utils .is_list_like (values ):
298
+ raise TypeError (
299
+ "only list-like objects are allowed to be passed to "
300
+ f"isin(), you passed a [{ type (values ).__name__ } ]"
301
+ )
214
302
215
- return Index (df .DataFrame (block .select_columns ([])))
303
+ return self ._apply_unary_op (ops .IsInOp (values , match_nulls = True )).fillna (
304
+ value = False
305
+ )
216
306
217
307
def _apply_unary_op (
218
308
self ,
@@ -226,9 +316,7 @@ def _apply_unary_op(
226
316
result_ids .append (result_id )
227
317
228
318
block = block .set_index (result_ids , index_labels = self ._block .index_labels )
229
- import bigframes .dataframe as df
230
-
231
- return Index (df .DataFrame (block ))
319
+ return Index ._from_block (block )
232
320
233
321
def _apply_aggregation (self , op : agg_ops .AggregateOp ) -> typing .Any :
234
322
if self .nlevels > 1 :
@@ -262,6 +350,12 @@ def to_numpy(self, dtype=None, **kwargs) -> np.ndarray:
262
350
def __len__ (self ):
263
351
return self .shape [0 ]
264
352
353
+ @classmethod
354
+ def _from_block (cls , block : blocks .Block ) -> Index :
355
+ import bigframes .dataframe as df
356
+
357
+ return Index (df .DataFrame (block ))
358
+
265
359
266
360
class IndexValue :
267
361
"""An immutable index."""
@@ -356,12 +450,6 @@ def resolve_level_name(self: IndexValue, label: blocks.Label) -> str:
356
450
def is_uniquely_named (self : IndexValue ):
357
451
return len (set (self .names )) == len (self .names )
358
452
359
- def _set_block (self , block : blocks .Block ):
360
- self ._block = block
361
-
362
- def _get_block (self ) -> blocks .Block :
363
- return self ._block
364
-
365
453
366
454
def join_mono_indexed (
367
455
left : IndexValue ,
0 commit comments