This is an automated email from the ASF dual-hosted git repository.

jiayu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sedona.git


The following commit(s) were added to refs/heads/master by this push:
     new 812923e675 [GH-2031] Geopandas.GeoSeries: Implement isna, notna and 
aliases (isnull, notnull) (#2032)
812923e675 is described below

commit 812923e675bb7e6000fe335bef3d18427802bbcc
Author: Peter Nguyen <[email protected]>
AuthorDate: Sun Jul 6 11:14:12 2025 -0700

    [GH-2031] Geopandas.GeoSeries: Implement isna, notna and aliases (isnull, 
notnull) (#2032)
    
    * Refactor process_geometry_column to create a more flexible 
query_geometry_column()
    
    * Implement length()
    
    * Implement isna and isnull
    
    * Implement notna
    
    * Fix doc strings to use sedona instead of geoseries
    
    * Update python/sedona/geopandas/geoseries.py
    
    Co-authored-by: Copilot <[email protected]>
    
    * Update python/sedona/geopandas/geoseries.py
    
    ---------
    
    Co-authored-by: Jia Yu <[email protected]>
    Co-authored-by: Copilot <[email protected]>
---
 python/sedona/geopandas/geoseries.py               | 85 +++++++++++++++++++++-
 python/tests/geopandas/test_geoseries.py           | 23 +++---
 .../tests/geopandas/test_match_geopandas_series.py | 28 ++++---
 3 files changed, 114 insertions(+), 22 deletions(-)

diff --git a/python/sedona/geopandas/geoseries.py 
b/python/sedona/geopandas/geoseries.py
index 146edaca8e..de5927c618 100644
--- a/python/sedona/geopandas/geoseries.py
+++ b/python/sedona/geopandas/geoseries.py
@@ -1826,13 +1826,92 @@ class GeoSeries(GeoFrame, pspd.Series):
         raise NotImplementedError("GeoSeries.to_file() is not implemented 
yet.")
 
     def isna(self) -> pspd.Series:
-        raise NotImplementedError("GeoSeries.isna() is not implemented yet.")
+        """
+        Detect missing values.
+
+        Returns
+        -------
+        A boolean Series of the same size as the GeoSeries,
+        True where a value is NA.
+
+        Examples
+        --------
+
+        >>> from sedona.geopandas import GeoSeries
+        >>> from shapely.geometry import Polygon
+        >>> s = GeoSeries(
+        ...     [Polygon([(0, 0), (1, 1), (0, 1)]), None, Polygon([])]
+        ... )
+        >>> s
+        0    POLYGON ((0 0, 1 1, 0 1, 0 0))
+        1                              None
+        2                     POLYGON EMPTY
+        dtype: geometry
+
+        >>> s.isna()
+        0    False
+        1     True
+        2    False
+        dtype: bool
+
+        See Also
+        --------
+        GeoSeries.notna : inverse of isna
+        GeoSeries.is_empty : detect empty geometries
+        """
+        col = self.get_first_geometry_column()
+        select = f"`{col}` IS NULL"
+        return (
+            self._query_geometry_column(select, col, rename="isna")
+            .to_spark_pandas()
+            .astype("bool")
+        )
 
     def isnull(self) -> pspd.Series:
-        raise NotImplementedError("GeoSeries.isnull() is not implemented yet.")
+        """Alias for `isna` method. See `isna` for more detail."""
+        return self.isna()
 
     def notna(self) -> pspd.Series:
-        raise NotImplementedError("GeoSeries.notna() is not implemented yet.")
+        """
+        Detect non-missing values.
+
+        Returns
+        -------
+        A boolean pandas Series of the same size as the GeoSeries,
+        False where a value is NA.
+
+        Examples
+        --------
+
+        >>> from sedona.geopandas import GeoSeries
+        >>> from shapely.geometry import Polygon
+        >>> s = GeoSeries(
+        ...     [Polygon([(0, 0), (1, 1), (0, 1)]), None, Polygon([])]
+        ... )
+        >>> s
+        0    POLYGON ((0 0, 1 1, 0 1, 0 0))
+        1                              None
+        2                     POLYGON EMPTY
+        dtype: geometry
+
+        >>> s.notna()
+        0     True
+        1    False
+        2     True
+        dtype: bool
+
+        See Also
+        --------
+        GeoSeries.isna : inverse of notna
+        GeoSeries.is_empty : detect empty geometries
+        """
+        col = self.get_first_geometry_column()
+        select = f"`{col}` IS NOT NULL"
+        return (
+            self._query_geometry_column(select, col, rename="notna")
+            .to_spark_pandas()
+            .astype("bool")
+        )
 
     def notnull(self) -> pspd.Series:
         """Alias for `notna` method. See `notna` for more detail."""
diff --git a/python/tests/geopandas/test_geoseries.py 
b/python/tests/geopandas/test_geoseries.py
index 9d73082dfd..e9caad3904 100644
--- a/python/tests/geopandas/test_geoseries.py
+++ b/python/tests/geopandas/test_geoseries.py
@@ -34,6 +34,7 @@ from shapely.geometry import (
     LinearRing,
 )
 from pandas.testing import assert_series_equal
+import pytest
 
 
 class TestGeoSeries(TestBase):
@@ -173,17 +174,19 @@ class TestGeoSeries(TestBase):
     def test_to_file(self):
         pass
 
-    def test_isna(self):
-        pass
-
-    def test_isnull(self):
-        pass
-
-    def test_notna(self):
-        pass
+    @pytest.mark.parametrize("fun", ["isna", "isnull"])
+    def test_isna(self, fun):
+        geoseries = GeoSeries([Polygon([(0, 0), (1, 1), (0, 1)]), None, 
Polygon([])])
+        result = getattr(geoseries, fun)()
+        expected = pd.Series([False, True, False])
+        assert_series_equal(result.to_pandas(), expected)
 
-    def test_notnull(self):
-        pass
+    @pytest.mark.parametrize("fun", ["notna", "notnull"])
+    def test_notna(self, fun):
+        geoseries = GeoSeries([Polygon([(0, 0), (1, 1), (0, 1)]), None, 
Polygon([])])
+        result = getattr(geoseries, fun)()
+        expected = pd.Series([True, False, True])
+        assert_series_equal(result.to_pandas(), expected)
 
     def test_fillna(self):
         pass
diff --git a/python/tests/geopandas/test_match_geopandas_series.py 
b/python/tests/geopandas/test_match_geopandas_series.py
index 3c3695aed7..3c159a7df9 100644
--- a/python/tests/geopandas/test_match_geopandas_series.py
+++ b/python/tests/geopandas/test_match_geopandas_series.py
@@ -284,17 +284,27 @@ class TestMatchGeopandasSeries(TestBase):
     def test_to_file(self):
         pass
 
-    def test_isna(self):
-        pass
-
-    def test_isnull(self):
-        pass
+    @pytest.mark.parametrize("fun", ["isna", "isnull"])
+    def test_isna(self, fun):
+        for _, geom in self.geoms:
+            sgpd_result = getattr(GeoSeries(geom), fun)()
+            assert isinstance(sgpd_result, ps.Series)
+            gpd_result = getattr(gpd.GeoSeries(geom), fun)()
+            self.check_pd_series_equal(sgpd_result, gpd_result)
 
-    def test_notna(self):
-        pass
+    @pytest.mark.parametrize("fun", ["notna", "notnull"])
+    def test_notna(self, fun):
+        for _, geom in self.geoms:
+            sgpd_result = getattr(GeoSeries(geom), fun)()
+            assert isinstance(sgpd_result, ps.Series)
+            gpd_result = getattr(gpd.GeoSeries(geom), fun)()
+            self.check_pd_series_equal(sgpd_result, gpd_result)
 
-    def test_notnull(self):
-        pass
+        data = [Point(0, 0), None]
+        series = GeoSeries(data)
+        sgpd_result = series.notna()
+        gpd_result = gpd.GeoSeries(data).notna()
+        self.check_pd_series_equal(sgpd_result, gpd_result)
 
     def test_fillna(self):
         pass

Reply via email to