diff --git a/CHANGES.md b/CHANGES.md index 354f971acc6c..89471aa5e6cf 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -105,6 +105,7 @@ * (Python) `Duration` built from float seconds now rounds to the nearest microsecond instead of truncating, which could lose a microsecond ([#40263](https://github.com/apache/beam/issues/40263)). * (Python) `ReadFromText` with `escapechar` no longer skips a delimiter that directly follows an escaped delimiter, which merged two records into one ([#40459](https://github.com/apache/beam/issues/40459)). * (Python) DataFrame API: `agg` with a list that includes `'count'` or `'size'` now labels those rows `count`/`size` instead of `sum` ([#40504](https://github.com/apache/beam/issues/40504)). +* (Python) DataFrame API: `Series.value_counts(bins=...)` no longer always fails with a `TypeError` ([#40503](https://github.com/apache/beam/issues/40503)). * Fixed X (Java/Python) ([#X](https://github.com/apache/beam/issues/X)). ## Security Fixes diff --git a/sdks/python/apache_beam/dataframe/frames.py b/sdks/python/apache_beam/dataframe/frames.py index ea634beadeec..500152f44905 100644 --- a/sdks/python/apache_beam/dataframe/frames.py +++ b/sdks/python/apache_beam/dataframe/frames.py @@ -2345,11 +2345,18 @@ def value_counts( reason="order-sensitive") if bins is not None: + # pandas can't compute bins for the empty proxy, so make the proxy from + # a single element of the same type. + proxy = self._expr.proxy() + proxy = pd.Series([0], dtype=proxy.dtype, name=proxy.name).value_counts( + normalize=normalize, bins=bins, dropna=dropna)[:0] return frame_base.DeferredFrame.wrap( expressions.ComputedExpression( 'value_counts', lambda s: s.value_counts( - normalize=normalize, bins=bins, dropna=dropna)[self._expr], + normalize=normalize, bins=bins, dropna=dropna), + [self._expr], + proxy=proxy, requires_partition_by=partitionings.Singleton( reason=( "value_counts with bin specified requires collecting " diff --git a/sdks/python/apache_beam/dataframe/frames_test.py b/sdks/python/apache_beam/dataframe/frames_test.py index 41f3a913fb70..67f61aa68c6a 100644 --- a/sdks/python/apache_beam/dataframe/frames_test.py +++ b/sdks/python/apache_beam/dataframe/frames_test.py @@ -796,6 +796,15 @@ def test_value_counts_with_nans(self): value_counts(dropna=dropna, normalize=normalize), df) + def test_series_value_counts_with_bins(self): + s = pd.Series([1, 2, 2, 3, 5, 8, 8, 9, np.nan]) + + self._run_test(lambda s: s.value_counts(bins=3), s, nonparallel=True) + self._run_test( + lambda s: s.value_counts(bins=3, normalize=True), s, nonparallel=True) + self._run_test( + lambda s: s.value_counts(bins=[0, 5, 10]), s, nonparallel=True) + def test_value_counts_does_not_support_sort(self): df = pd.DataFrame({ 'num_legs': [2, 4, 4, 6, np.nan, np.nan],