jiayuasu opened a new issue, #3218:
URL: https://github.com/apache/sedona/issues/3218

   ## Expected behavior
   
   `Moran.getGlobal` / `Moran.get_global` should work when the value column is 
an integer type (e.g. counts produced by `COUNT(*)`), or fail with a clear 
message asking for a numeric cast.
   
   ## Actual behavior
   
   When the value column is a `LONG` (or other integer type), the computation 
fails with:
   
   ```
   pyspark.errors.exceptions.captured.AnalysisException: 
[CANNOT_UP_CAST_DATATYPE]
   Cannot up cast `sum(z2ss_comp)` from "DECIMAL(38,6)" to "DOUBLE".
   ```
   
   Root cause: in 
`spark/common/src/main/scala/org/apache/sedona/stats/autocorrelation/Moran.scala`,
 the intermediate expressions (`z * z AS z2ss_comp`, line 95; summed at line 
97) inherit decimal types when the input column is integral, but the results 
are consumed through typed `Dataset.as[(Double, Double, Double)]` (lines 79 and 
107), which cannot up-cast `DECIMAL(38,6)` to `DOUBLE`.
   
   Casting the value column to `DOUBLE` before calling the function works, e.g. 
`CAST(COUNT(*) AS DOUBLE)`, which confirms the diagnosis.
   
   Suggested fix: defensively cast the value column to `DoubleType` at the 
start of `getGlobal` (or document that the value column must be a 
floating-point type). Counts are the most natural input for spatial 
autocorrelation on aggregated data, so the integer case is common.
   
   ## Steps to reproduce the problem
   
   ```python
   from sedona.spark import SedonaContext
   from sedona.spark.stats.weighting import add_binary_distance_band_column
   from sedona.spark.stats.autocorrelation.moran import Moran
   
   sedona = 
SedonaContext.create(SedonaContext.builder().master("local[*]").getOrCreate())
   
   # any point dataset; aggregate to cells with an *integer* count column
   pois = sedona.read.format("shapefile").load("docs/usecases/data")
   pois.createOrReplaceTempView("pois")
   cells = sedona.sql("""
       SELECT ST_GeoHash(geometry, 5) AS id,
              COUNT(*)                AS poi_count,   -- LONG: triggers the 
failure
              ST_Centroid(ST_Envelope_Aggr(geometry)) AS geometry
       FROM pois GROUP BY ST_GeoHash(geometry, 5)
   """)
   
   weighted = add_binary_distance_band_column(
       cells, 0.08, include_self=False, saved_attributes=["id", "poi_count"]
   )
   Moran.get_global(weighted, value_column="poi_count", id_column="id")
   # -> AnalysisException: CANNOT_UP_CAST_DATATYPE ... DECIMAL(38,6) to DOUBLE
   
   # Workaround: CAST(COUNT(*) AS DOUBLE) in the aggregation makes it succeed
   # (verified: I = 0.2519, z = 12.69 on the bundled dataset above).
   ```
   
   ## Settings
   
   Sedona version = master (1.9.1-SNAPSHOT); Moran introduced in 1.8.0
   
   Apache Spark version = 3.4.4
   
   Apache Flink version = N/A
   
   API type = Python (the Scala path has the same typed casts)
   
   Scala version = 2.12
   
   JRE version = 11
   
   Python version = 3.12
   
   Environment = Standalone (local[*])
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to