Skip to content

Commit 6b08718

Browse files
Merge remote-tracking branch 'github/main' into selection_defer_plus
2 parents 729dc54 + c62e553 commit 6b08718

File tree

32 files changed

+500
-97
lines changed

32 files changed

+500
-97
lines changed

.github/workflows/docs.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ on:
22
pull_request:
33
branches:
44
- main
5+
push:
6+
branches:
7+
- main
58
name: docs
69
jobs:
710
docs:

.github/workflows/lint.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ on:
22
pull_request:
33
branches:
44
- main
5+
push:
6+
branches:
7+
- main
58
name: lint
69
jobs:
710
lint:

.github/workflows/mypy.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ on:
22
pull_request:
33
branches:
44
- main
5+
push:
6+
branches:
7+
- main
58
name: mypy
69
jobs:
710
mypy:

.github/workflows/unittest.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ on:
22
pull_request:
33
branches:
44
- main
5+
push:
6+
branches:
7+
- main
58
name: unittest
69
jobs:
710
unit:

CHANGELOG.md

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

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

7+
## [2.29.0](https://github.com/googleapis/python-bigquery-dataframes/compare/v2.28.0...v2.29.0) (2025-11-10)
8+
9+
10+
### Features
11+
12+
* Add bigframes.bigquery.st_regionstats to join raster data from Earth Engine ([#2228](https://github.com/googleapis/python-bigquery-dataframes/issues/2228)) ([10ec52f](https://github.com/googleapis/python-bigquery-dataframes/commit/10ec52f30a0a9c61b9eda9cf4f9bd6aa0cd95db5))
13+
* Add DataFrame.resample and Series.resample ([#2213](https://github.com/googleapis/python-bigquery-dataframes/issues/2213)) ([c9ca02c](https://github.com/googleapis/python-bigquery-dataframes/commit/c9ca02c5194c8b8e9b940eddd2224efd2ff0d5d9))
14+
* SQL Cell no longer escapes formatted string values ([#2245](https://github.com/googleapis/python-bigquery-dataframes/issues/2245)) ([d2d38f9](https://github.com/googleapis/python-bigquery-dataframes/commit/d2d38f94ed8333eae6f9cff3833177756eefe85a))
15+
* Support left_index and right_index for merge ([#2220](https://github.com/googleapis/python-bigquery-dataframes/issues/2220)) ([da9ba26](https://github.com/googleapis/python-bigquery-dataframes/commit/da9ba267812c01ffa6fa0b09943d7a4c63b8f187))
16+
17+
18+
### Bug Fixes
19+
20+
* Correctly iterate over null struct values in ManagedArrowTable ([#2209](https://github.com/googleapis/python-bigquery-dataframes/issues/2209)) ([12e04d5](https://github.com/googleapis/python-bigquery-dataframes/commit/12e04d55f0d6aef1297b7ca773935aecf3313ee7))
21+
* Simplify UnsupportedTypeError message ([#2212](https://github.com/googleapis/python-bigquery-dataframes/issues/2212)) ([6c9a18d](https://github.com/googleapis/python-bigquery-dataframes/commit/6c9a18d7e67841c6fe6c1c6f34f80b950815141f))
22+
* Support results with STRUCT and ARRAY columns containing JSON subfields in `to_pandas_batches()` ([#2216](https://github.com/googleapis/python-bigquery-dataframes/issues/2216)) ([3d8b17f](https://github.com/googleapis/python-bigquery-dataframes/commit/3d8b17fa5eb9bbfc9e151031141a419f2dc3acb4))
23+
24+
25+
### Documentation
26+
27+
* Switch API reference docs to pydata theme ([#2237](https://github.com/googleapis/python-bigquery-dataframes/issues/2237)) ([9b86dcf](https://github.com/googleapis/python-bigquery-dataframes/commit/9b86dcf87929648bf5ab565dfd46a23b639f01ac))
28+
* Update notebook for JSON subfields support in to_pandas_batches() ([#2138](https://github.com/googleapis/python-bigquery-dataframes/issues/2138)) ([5663d2a](https://github.com/googleapis/python-bigquery-dataframes/commit/5663d2a18064589596558af109e915f87d426eb0))
29+
730
## [2.28.0](https://github.com/googleapis/python-bigquery-dataframes/compare/v2.27.0...v2.28.0) (2025-11-03)
831

932

bigframes/core/compile/sqlglot/expressions/geo_ops.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import bigframes.core.compile.sqlglot.scalar_compiler as scalar_compiler
2222

2323
register_unary_op = scalar_compiler.scalar_op_compiler.register_unary_op
24+
register_binary_op = scalar_compiler.scalar_op_compiler.register_binary_op
2425

2526

2627
@register_unary_op(ops.geo_area_op)
@@ -108,3 +109,8 @@ def _(expr: TypedExpr) -> sge.Expression:
108109
@register_unary_op(ops.geo_y_op)
109110
def _(expr: TypedExpr) -> sge.Expression:
110111
return sge.func("SAFE.ST_Y", expr.expr)
112+
113+
114+
@register_binary_op(ops.geo_st_difference_op)
115+
def _(left: TypedExpr, right: TypedExpr) -> sge.Expression:
116+
return sge.func("ST_DIFFERENCE", left.expr, right.expr)

bigframes/core/compile/sqlglot/expressions/numeric_ops.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ def _(expr: TypedExpr) -> sge.Expression:
7777
return sge.func("ASINH", expr.expr)
7878

7979

80+
@register_binary_op(ops.arctan2_op)
81+
def _(left: TypedExpr, right: TypedExpr) -> sge.Expression:
82+
left_expr = _coerce_bool_to_int(left)
83+
right_expr = _coerce_bool_to_int(right)
84+
return sge.func("ATAN2", left_expr, right_expr)
85+
86+
8087
@register_unary_op(ops.arctan_op)
8188
def _(expr: TypedExpr) -> sge.Expression:
8289
return sge.func("ATAN", expr.expr)
@@ -118,6 +125,18 @@ def _(expr: TypedExpr) -> sge.Expression:
118125
)
119126

120127

128+
@register_binary_op(ops.cosine_distance_op)
129+
def _(left: TypedExpr, right: TypedExpr) -> sge.Expression:
130+
return sge.Anonymous(
131+
this="ML.DISTANCE",
132+
expressions=[
133+
left.expr,
134+
right.expr,
135+
sge.Literal.string("COSINE"),
136+
],
137+
)
138+
139+
121140
@register_unary_op(ops.exp_op)
122141
def _(expr: TypedExpr) -> sge.Expression:
123142
return sge.Case(

bigframes/core/local_data.py

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -253,9 +253,16 @@ def _(
253253
value_generator = iter_array(
254254
array.flatten(), bigframes.dtypes.get_array_inner_type(dtype)
255255
)
256-
for (start, end) in _pairwise(array.offsets):
257-
arr_size = end.as_py() - start.as_py()
258-
yield list(itertools.islice(value_generator, arr_size))
256+
offset_generator = iter_array(array.offsets, bigframes.dtypes.INT_DTYPE)
257+
258+
start_offset = None
259+
end_offset = None
260+
for offset in offset_generator:
261+
start_offset = end_offset
262+
end_offset = offset
263+
if start_offset is not None:
264+
arr_size = end_offset - start_offset
265+
yield list(itertools.islice(value_generator, arr_size))
259266

260267
@iter_array.register
261268
def _(
@@ -267,8 +274,15 @@ def _(
267274
sub_generators[field_name] = iter_array(array.field(field_name), dtype)
268275

269276
keys = list(sub_generators.keys())
270-
for row_values in zip(*sub_generators.values()):
271-
yield {key: value for key, value in zip(keys, row_values)}
277+
is_null_generator = iter_array(array.is_null(), bigframes.dtypes.BOOL_DTYPE)
278+
279+
for values in zip(is_null_generator, *sub_generators.values()):
280+
is_row_null = values[0]
281+
row_values = values[1:]
282+
if not is_row_null:
283+
yield {key: value for key, value in zip(keys, row_values)}
284+
else:
285+
yield None
272286

273287
for batch in table.to_batches():
274288
sub_generators: dict[str, Generator[Any, None, None]] = {}
@@ -491,16 +505,3 @@ def _schema_durations_to_ints(schema: pa.Schema) -> pa.Schema:
491505
return pa.schema(
492506
pa.field(field.name, _durations_to_ints(field.type)) for field in schema
493507
)
494-
495-
496-
def _pairwise(iterable):
497-
do_yield = False
498-
a = None
499-
b = None
500-
for item in iterable:
501-
a = b
502-
b = item
503-
if do_yield:
504-
yield (a, b)
505-
else:
506-
do_yield = True

bigframes/core/pyformat.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ def _field_to_template_value(
104104
if isinstance(value, bigframes.dataframe.DataFrame):
105105
return _table_to_sql(value._to_placeholder_table(dry_run=dry_run))
106106

107+
if isinstance(value, str):
108+
return value
109+
107110
return bigframes.core.sql.simple_literal(value)
108111

109112

bigframes/core/reshape/api.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from bigframes.core.reshape.concat import concat
1616
from bigframes.core.reshape.encoding import get_dummies
1717
from bigframes.core.reshape.merge import merge
18+
from bigframes.core.reshape.pivot import crosstab
1819
from bigframes.core.reshape.tile import cut, qcut
1920

20-
__all__ = ["concat", "get_dummies", "merge", "cut", "qcut"]
21+
__all__ = ["concat", "get_dummies", "merge", "cut", "qcut", "crosstab"]

0 commit comments

Comments
 (0)