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

Commit 859aa90

Browse files
Merge remote-tracking branch 'github/main' into groupby_describe
2 parents 21a5b84 + 090ce8e commit 859aa90

40 files changed

+1142
-853
lines changed

CHANGELOG.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,37 @@
44

55
[1]: https://pypi.org/project/bigframes/#history
66

7+
## [2.20.0](https://github.com/googleapis/python-bigquery-dataframes/compare/v2.19.0...v2.20.0) (2025-09-16)
8+
9+
10+
### Features
11+
12+
* Add `__dataframe__` interchange support ([#2063](https://github.com/googleapis/python-bigquery-dataframes/issues/2063)) ([3b46a0d](https://github.com/googleapis/python-bigquery-dataframes/commit/3b46a0d91eb379c61ced45ae0b25339281326c3d))
13+
* Add ai_generate_bool to the bigframes.bigquery package ([#2060](https://github.com/googleapis/python-bigquery-dataframes/issues/2060)) ([70d6562](https://github.com/googleapis/python-bigquery-dataframes/commit/70d6562df64b2aef4ff0024df6f57702d52dcaf8))
14+
* Add bigframes.bigquery.to_json_string ([#2076](https://github.com/googleapis/python-bigquery-dataframes/issues/2076)) ([41e8f33](https://github.com/googleapis/python-bigquery-dataframes/commit/41e8f33ceb46a7c2a75d1c59a4a3f2f9413d281d))
15+
* Add rank(pct=True) support ([#2084](https://github.com/googleapis/python-bigquery-dataframes/issues/2084)) ([c1e871d](https://github.com/googleapis/python-bigquery-dataframes/commit/c1e871d9327bf6c920d17e1476fed3088d506f5f))
16+
* Add StreamingDataFrame.to_bigtable and .to_pubsub start_timestamp parameter ([#2066](https://github.com/googleapis/python-bigquery-dataframes/issues/2066)) ([a63cbae](https://github.com/googleapis/python-bigquery-dataframes/commit/a63cbae24ff2dc191f0a53dced885bc95f38ec96))
17+
* Can call agg with some callables ([#2055](https://github.com/googleapis/python-bigquery-dataframes/issues/2055)) ([17a1ed9](https://github.com/googleapis/python-bigquery-dataframes/commit/17a1ed99ec8c6d3215d3431848814d5d458d4ff1))
18+
* Support astype to json ([#2073](https://github.com/googleapis/python-bigquery-dataframes/issues/2073)) ([6bd6738](https://github.com/googleapis/python-bigquery-dataframes/commit/6bd67386341de7a92ada948381702430c399406e))
19+
* Support pandas.Index as key for DataFrame.__setitem__() ([#2062](https://github.com/googleapis/python-bigquery-dataframes/issues/2062)) ([b3cf824](https://github.com/googleapis/python-bigquery-dataframes/commit/b3cf8248e3b8ea76637ded64fb12028d439448d1))
20+
* Support pd.cut() for array-like type ([#2064](https://github.com/googleapis/python-bigquery-dataframes/issues/2064)) ([21eb213](https://github.com/googleapis/python-bigquery-dataframes/commit/21eb213c5f0e0f696f2d1ca1f1263678d791cf7c))
21+
* Support to cast struct to json ([#2067](https://github.com/googleapis/python-bigquery-dataframes/issues/2067)) ([b0ff718](https://github.com/googleapis/python-bigquery-dataframes/commit/b0ff718a04fadda33cfa3613b1d02822cde34bc2))
22+
23+
24+
### Bug Fixes
25+
26+
* Deflake ai_gen_bool multimodel test ([#2085](https://github.com/googleapis/python-bigquery-dataframes/issues/2085)) ([566a37a](https://github.com/googleapis/python-bigquery-dataframes/commit/566a37a30ad5677aef0c5f79bdd46bca2139cc1e))
27+
* Do not scroll page selector in anywidget `repr_mode` ([#2082](https://github.com/googleapis/python-bigquery-dataframes/issues/2082)) ([5ce5d63](https://github.com/googleapis/python-bigquery-dataframes/commit/5ce5d63fcb51bfb3df2769108b7486287896ccb9))
28+
* Fix the potential invalid VPC egress configuration ([#2068](https://github.com/googleapis/python-bigquery-dataframes/issues/2068)) ([cce4966](https://github.com/googleapis/python-bigquery-dataframes/commit/cce496605385f2ac7ab0becc0773800ed5901aa5))
29+
* Return a DataFrame containing query stats for all non-SELECT statements ([#2071](https://github.com/googleapis/python-bigquery-dataframes/issues/2071)) ([a52b913](https://github.com/googleapis/python-bigquery-dataframes/commit/a52b913d9d8794b4b959ea54744a38d9f2f174e7))
30+
* Use the remote and managed functions for bigframes results ([#2079](https://github.com/googleapis/python-bigquery-dataframes/issues/2079)) ([49b91e8](https://github.com/googleapis/python-bigquery-dataframes/commit/49b91e878de651de23649756259ee35709e3f5a8))
31+
32+
33+
### Performance Improvements
34+
35+
* Avoid re-authenticating if credentials have already been fetched ([#2058](https://github.com/googleapis/python-bigquery-dataframes/issues/2058)) ([913de1b](https://github.com/googleapis/python-bigquery-dataframes/commit/913de1b31f3bb0b306846fddae5dcaff6be3cec4))
36+
* Improve apply axis=1 performance ([#2077](https://github.com/googleapis/python-bigquery-dataframes/issues/2077)) ([12e4380](https://github.com/googleapis/python-bigquery-dataframes/commit/12e438051134577e911c1a6ce9d5a5885a0b45ad))
37+
738
## [2.19.0](https://github.com/googleapis/python-bigquery-dataframes/compare/v2.18.0...v2.19.0) (2025-09-09)
839

940

bigframes/bigquery/_operations/ai.py

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -47,30 +47,13 @@ def generate_bool(
4747
... "col_1": ["apple", "bear", "pear"],
4848
... "col_2": ["fruit", "animal", "animal"]
4949
... })
50-
>>> bbq.ai_generate_bool((df["col_1"], " is a ", df["col_2"]))
50+
>>> bbq.ai.generate_bool((df["col_1"], " is a ", df["col_2"]))
5151
0 {'result': True, 'full_response': '{"candidate...
5252
1 {'result': True, 'full_response': '{"candidate...
5353
2 {'result': False, 'full_response': '{"candidat...
5454
dtype: struct<result: bool, full_response: string, status: string>[pyarrow]
5555
56-
>>> bbq.ai_generate_bool((df["col_1"], " is a ", df["col_2"])).struct.field("result")
57-
0 True
58-
1 True
59-
2 False
60-
Name: result, dtype: boolean
61-
62-
>>> model_params = {
63-
... "generation_config": {
64-
... "thinking_config": {
65-
... "thinking_budget": 0
66-
... }
67-
... }
68-
... }
69-
>>> bbq.ai_generate_bool(
70-
... (df["col_1"], " is a ", df["col_2"]),
71-
... endpoint="gemini-2.5-pro",
72-
... model_params=model_params,
73-
... ).struct.field("result")
56+
>>> bbq.ai.generate_bool((df["col_1"], " is a ", df["col_2"])).struct.field("result")
7457
0 True
7558
1 True
7659
2 False

bigframes/core/agg_expressions.py

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from typing import Callable, Mapping, TypeVar
2323

2424
from bigframes import dtypes
25-
from bigframes.core import expression
25+
from bigframes.core import expression, window_spec
2626
import bigframes.core.identifiers as ids
2727
import bigframes.operations.aggregations as agg_ops
2828

@@ -149,3 +149,68 @@ def replace_args(
149149
self, larg: expression.Expression, rarg: expression.Expression
150150
) -> BinaryAggregation:
151151
return BinaryAggregation(self.op, larg, rarg)
152+
153+
154+
@dataclasses.dataclass(frozen=True)
155+
class WindowExpression(expression.Expression):
156+
analytic_expr: Aggregation
157+
window: window_spec.WindowSpec
158+
159+
@property
160+
def column_references(self) -> typing.Tuple[ids.ColumnId, ...]:
161+
return tuple(
162+
itertools.chain.from_iterable(
163+
map(lambda x: x.column_references, self.inputs)
164+
)
165+
)
166+
167+
@functools.cached_property
168+
def is_resolved(self) -> bool:
169+
return all(input.is_resolved for input in self.inputs)
170+
171+
@property
172+
def output_type(self) -> dtypes.ExpressionType:
173+
return self.analytic_expr.output_type
174+
175+
@property
176+
def inputs(
177+
self,
178+
) -> typing.Tuple[expression.Expression, ...]:
179+
return (self.analytic_expr, *self.window.expressions)
180+
181+
@property
182+
def free_variables(self) -> typing.Tuple[str, ...]:
183+
return tuple(
184+
itertools.chain.from_iterable(map(lambda x: x.free_variables, self.inputs))
185+
)
186+
187+
@property
188+
def is_const(self) -> bool:
189+
return all(child.is_const for child in self.inputs)
190+
191+
def transform_children(
192+
self: WindowExpression,
193+
t: Callable[[expression.Expression], expression.Expression],
194+
) -> WindowExpression:
195+
return WindowExpression(
196+
self.analytic_expr.transform_children(t),
197+
self.window.transform_exprs(t),
198+
)
199+
200+
def bind_variables(
201+
self: WindowExpression,
202+
bindings: Mapping[str, expression.Expression],
203+
allow_partial_bindings: bool = False,
204+
) -> WindowExpression:
205+
return self.transform_children(
206+
lambda x: x.bind_variables(bindings, allow_partial_bindings)
207+
)
208+
209+
def bind_refs(
210+
self: WindowExpression,
211+
bindings: Mapping[ids.ColumnId, expression.Expression],
212+
allow_partial_bindings: bool = False,
213+
) -> WindowExpression:
214+
return self.transform_children(
215+
lambda x: x.bind_refs(bindings, allow_partial_bindings)
216+
)

bigframes/core/block_transforms.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ def rank(
417417
ascending: bool = True,
418418
grouping_cols: tuple[str, ...] = (),
419419
columns: tuple[str, ...] = (),
420+
pct: bool = False,
420421
):
421422
if method not in ["average", "min", "max", "first", "dense"]:
422423
raise ValueError(
@@ -459,6 +460,12 @@ def rank(
459460
),
460461
skip_reproject_unsafe=(col != columns[-1]),
461462
)
463+
if pct:
464+
block, max_id = block.apply_window_op(
465+
rownum_id, agg_ops.max_op, windows.unbound(grouping_keys=grouping_cols)
466+
)
467+
block, rownum_id = block.project_expr(ops.div_op.as_expr(rownum_id, max_id))
468+
462469
rownum_col_ids.append(rownum_id)
463470

464471
# Step 2: Apply aggregate to groups of like input values.

bigframes/core/blocks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1177,7 +1177,7 @@ def apply_analytic(
11771177
block = self
11781178
if skip_null_groups:
11791179
for key in window.grouping_keys:
1180-
block = block.filter(ops.notnull_op.as_expr(key.id.name))
1180+
block = block.filter(ops.notnull_op.as_expr(key))
11811181
expr, result_id = block._expr.project_window_expr(
11821182
agg_expr,
11831183
window,

0 commit comments

Comments
 (0)