Skip to content
This repository was archived by the owner on Apr 1, 2026. It is now read-only.

Commit 42c3f9f

Browse files
committed
Merge branch 'main' into shuowei-anywidget-cell-visual
2 parents 609d0ce + ae5c8b3 commit 42c3f9f

File tree

8 files changed

+59
-7
lines changed

8 files changed

+59
-7
lines changed

bigframes/bigquery/_operations/ai.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1018,7 +1018,7 @@ def _convert_series(
10181018

10191019
def _resolve_connection_id(series: series.Series, connection_id: str | None):
10201020
return clients.get_canonical_bq_connection_id(
1021-
connection_id or series._session._bq_connection,
1021+
connection_id or series._session.bq_connection,
10221022
series._session._project,
10231023
series._session._location,
10241024
)

bigframes/core/array_value.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,12 @@ def filter_by_id(self, predicate_id: str, keep_null: bool = False) -> ArrayValue
204204
return self.filter(predicate)
205205

206206
def filter(self, predicate: ex.Expression):
207-
return ArrayValue(nodes.FilterNode(child=self.node, predicate=predicate))
207+
if predicate.is_scalar_expr:
208+
return ArrayValue(nodes.FilterNode(child=self.node, predicate=predicate))
209+
else:
210+
arr, filter_ids = self.compute_general_expression([predicate])
211+
arr = arr.filter_by_id(filter_ids[0])
212+
return arr.drop_columns(filter_ids)
208213

209214
def order_by(
210215
self, by: Sequence[OrderingExpression], is_total_order: bool = False

bigframes/core/indexers.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import pandas as pd
2424

2525
import bigframes.core.blocks
26+
import bigframes.core.col
2627
import bigframes.core.expression as ex
2728
import bigframes.core.guid as guid
2829
import bigframes.core.indexes as indexes
@@ -36,7 +37,11 @@
3637

3738
if typing.TYPE_CHECKING:
3839
LocSingleKey = Union[
39-
bigframes.series.Series, indexes.Index, slice, bigframes.core.scalar.Scalar
40+
bigframes.series.Series,
41+
indexes.Index,
42+
slice,
43+
bigframes.core.scalar.Scalar,
44+
bigframes.core.col.Expression,
4045
]
4146

4247

@@ -309,6 +314,15 @@ def _loc_getitem_series_or_dataframe(
309314
raise NotImplementedError(
310315
f"loc does not yet support indexing with a slice. {constants.FEEDBACK_LINK}"
311316
)
317+
if isinstance(key, bigframes.core.col.Expression):
318+
label_to_col_ref = {
319+
label: ex.deref(id)
320+
for id, label in series_or_dataframe._block.col_id_to_label.items()
321+
}
322+
resolved_expr = key._value.bind_variables(label_to_col_ref)
323+
result = series_or_dataframe.copy()
324+
result._set_block(series_or_dataframe._block.filter(resolved_expr))
325+
return result
312326
if callable(key):
313327
raise NotImplementedError(
314328
f"loc does not yet support indexing with a callable. {constants.FEEDBACK_LINK}"

bigframes/dataframe.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,13 +623,18 @@ def __getitem__(
623623
): # No return type annotations (like pandas) as type cannot always be determined statically
624624
# NOTE: This implements the operations described in
625625
# https://pandas.pydata.org/docs/getting_started/intro_tutorials/03_subset_data.html
626+
import bigframes.core.col
627+
import bigframes.pandas
626628

627-
if isinstance(key, bigframes.series.Series):
629+
if isinstance(key, bigframes.pandas.Series):
628630
return self._getitem_bool_series(key)
629631

630632
if isinstance(key, slice):
631633
return self.iloc[key]
632634

635+
if isinstance(key, bigframes.core.col.Expression):
636+
return self.loc[key]
637+
633638
# TODO(tswast): Fix this pylance warning: Class overlaps "Hashable"
634639
# unsafely and could produce a match at runtime
635640
if isinstance(key, blocks.Label):

bigframes/functions/_function_session.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ def _resolve_bigquery_connection_id(
162162
) -> str:
163163
"""Resolves BigQuery connection id."""
164164
if not bigquery_connection:
165-
bigquery_connection = session._bq_connection # type: ignore
165+
bigquery_connection = session.bq_connection # type: ignore
166166

167167
bigquery_connection = clients.get_canonical_bq_connection_id(
168168
bigquery_connection,

bigframes/operations/blob.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ def _resolve_connection(self, connection: Optional[str] = None) -> str:
311311
Raises:
312312
ValueError: If the connection cannot be resolved to a valid string.
313313
"""
314-
connection = connection or self._data._block.session._bq_connection
314+
connection = connection or self._data._block.session.bq_connection
315315
return clients.get_canonical_bq_connection_id(
316316
connection,
317317
default_project=self._data._block.session._project,

bigframes/session/__init__.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,16 @@ def _allows_ambiguity(self) -> bool:
374374
def _anonymous_dataset(self):
375375
return self._anon_dataset_manager.dataset
376376

377+
@property
378+
def bq_connection(self) -> str:
379+
msg = bfe.format_message(
380+
f"""You are using the BigFrames session default connection: {self._bq_connection},
381+
which can be different from the BigQuery project default connection.
382+
This default connection may change in the future."""
383+
)
384+
warnings.warn(msg, category=FutureWarning)
385+
return self._bq_connection
386+
377387
def __hash__(self):
378388
# Stable hash needed to use in expression tree
379389
return hash(str(self._session_id))
@@ -2253,7 +2263,7 @@ def _create_bq_connection(
22532263
) -> str:
22542264
"""Create the connection with the session settings and try to attach iam role to the connection SA.
22552265
If any of project, location or connection isn't specified, use the session defaults. Returns fully-qualified connection name."""
2256-
connection = self._bq_connection if not connection else connection
2266+
connection = self.bq_connection if not connection else connection
22572267
connection = bigframes.clients.get_canonical_bq_connection_id(
22582268
connection_id=connection,
22592269
default_project=self._project,

tests/unit/test_col.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,21 @@ def test_pd_col_binary_bool_operators(scalars_dfs, op):
158158
pd_result = scalars_pandas_df.assign(**pd_kwargs)
159159

160160
assert_frame_equal(bf_result, pd_result)
161+
162+
163+
def test_loc_with_pd_col(scalars_dfs):
164+
scalars_df, scalars_pandas_df = scalars_dfs
165+
166+
bf_result = scalars_df.loc[bpd.col("float64_col") > 4].to_pandas()
167+
pd_result = scalars_pandas_df.loc[pd.col("float64_col") > 4] # type: ignore
168+
169+
assert_frame_equal(bf_result, pd_result)
170+
171+
172+
def test_getitem_with_pd_col(scalars_dfs):
173+
scalars_df, scalars_pandas_df = scalars_dfs
174+
175+
bf_result = scalars_df[bpd.col("float64_col") > 4].to_pandas()
176+
pd_result = scalars_pandas_df[pd.col("float64_col") > 4] # type: ignore
177+
178+
assert_frame_equal(bf_result, pd_result)

0 commit comments

Comments
 (0)