Skip to content

Commit ddfd02a

Browse files
authored
feat: iloc multiple columns selection. (#1437)
* feat: iloc multiple columns selection. * updates * refactor code
1 parent ecbf77d commit ddfd02a

File tree

2 files changed

+41
-17
lines changed

2 files changed

+41
-17
lines changed

bigframes/core/indexers.py

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ def _iloc_getitem_series_or_dataframe(
425425
@typing.overload
426426
def _iloc_getitem_series_or_dataframe(
427427
series_or_dataframe: bigframes.dataframe.DataFrame, key
428-
) -> Union[bigframes.dataframe.DataFrame, pd.Series]:
428+
) -> Union[bigframes.dataframe.DataFrame, pd.Series, bigframes.core.scalar.Scalar]:
429429
...
430430

431431

@@ -447,18 +447,29 @@ def _iloc_getitem_series_or_dataframe(
447447
return result_pd_df.iloc[0]
448448
elif isinstance(key, slice):
449449
return series_or_dataframe._slice(key.start, key.stop, key.step)
450-
elif isinstance(key, tuple) and len(key) == 0:
451-
return series_or_dataframe
452-
elif isinstance(key, tuple) and len(key) == 1:
453-
return _iloc_getitem_series_or_dataframe(series_or_dataframe, key[0])
454-
elif (
455-
isinstance(key, tuple)
456-
and isinstance(series_or_dataframe, bigframes.dataframe.DataFrame)
457-
and len(key) == 2
458-
):
459-
return series_or_dataframe.iat[key]
460450
elif isinstance(key, tuple):
461-
raise pd.errors.IndexingError("Too many indexers")
451+
if len(key) > 2 or (
452+
len(key) == 2 and isinstance(series_or_dataframe, bigframes.series.Series)
453+
):
454+
raise pd.errors.IndexingError("Too many indexers")
455+
456+
if len(key) == 0:
457+
return series_or_dataframe
458+
459+
if len(key) == 1:
460+
return _iloc_getitem_series_or_dataframe(series_or_dataframe, key[0])
461+
462+
# len(key) == 2
463+
if isinstance(key[1], int):
464+
return series_or_dataframe.iat[key]
465+
elif isinstance(key[1], list):
466+
columns = series_or_dataframe.columns[key[1]]
467+
return _iloc_getitem_series_or_dataframe(
468+
series_or_dataframe[columns], key[0]
469+
)
470+
raise NotImplementedError(
471+
f"iloc does not yet support indexing with {key}. {constants.FEEDBACK_LINK}"
472+
)
462473
elif pd.api.types.is_list_like(key):
463474
if len(key) == 0:
464475
return typing.cast(
@@ -491,11 +502,6 @@ def _iloc_getitem_series_or_dataframe(
491502
result = result.rename(original_series_name)
492503

493504
return result
494-
495-
elif isinstance(key, tuple):
496-
raise NotImplementedError(
497-
f"iloc does not yet support indexing with a (row, column) tuple. {constants.FEEDBACK_LINK}"
498-
)
499505
elif callable(key):
500506
raise NotImplementedError(
501507
f"iloc does not yet support indexing with a callable. {constants.FEEDBACK_LINK}"

tests/system/small/test_dataframe.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3414,6 +3414,24 @@ def test_iloc_tuple(scalars_df_index, scalars_pandas_df_index, index):
34143414
assert bf_result == pd_result
34153415

34163416

3417+
@pytest.mark.parametrize(
3418+
"index",
3419+
[(slice(None), [1, 2, 3]), (slice(1, 7, 2), [2, 5, 3])],
3420+
)
3421+
def test_iloc_tuple_multi_columns(scalars_df_index, scalars_pandas_df_index, index):
3422+
bf_result = scalars_df_index.iloc[index].to_pandas()
3423+
pd_result = scalars_pandas_df_index.iloc[index]
3424+
3425+
pd.testing.assert_frame_equal(bf_result, pd_result)
3426+
3427+
3428+
def test_iloc_tuple_multi_columns_single_row(scalars_df_index, scalars_pandas_df_index):
3429+
index = (2, [2, 1, 3, -4])
3430+
bf_result = scalars_df_index.iloc[index]
3431+
pd_result = scalars_pandas_df_index.iloc[index]
3432+
pd.testing.assert_series_equal(bf_result, pd_result)
3433+
3434+
34173435
@pytest.mark.parametrize(
34183436
("index", "error"),
34193437
[

0 commit comments

Comments
 (0)