core-lens 0.1.dev148__tar.gz → 0.1.dev150__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/PKG-INFO +1 -1
  2. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/_version.py +2 -2
  3. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/base/result.py +7 -4
  4. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/utils/polars_utils.py +10 -2
  5. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/.github/ISSUE_TEMPLATE/blank-proposal.yaml +0 -0
  6. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/.github/ISSUE_TEMPLATE/bug-report.yaml +0 -0
  7. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/.github/ISSUE_TEMPLATE/feature-request.yaml +0 -0
  8. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/.github/pull_request_template.md +0 -0
  9. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/.github/workflows/ci.yml +0 -0
  10. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/.github/workflows/gh-pages.yml +0 -0
  11. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/.github/workflows/pre-release.yml +0 -0
  12. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/.github/workflows/release.yml +0 -0
  13. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/.gitignore +0 -0
  14. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/.gitmessage +0 -0
  15. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/.pre-commit-config.yaml +0 -0
  16. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/.python-version +0 -0
  17. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/CONTRIBUTING.md +0 -0
  18. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/LICENSE +0 -0
  19. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/README.md +0 -0
  20. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/SKILLS.md +0 -0
  21. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/benchmarks/README.md +0 -0
  22. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/benchmarks/bench_aoi.py +0 -0
  23. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/benchmarks/bench_export.py +0 -0
  24. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/benchmarks/bench_polars_utils.py +0 -0
  25. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/benchmarks/bench_result.py +0 -0
  26. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/benchmarks/bench_schema.py +0 -0
  27. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/benchmarks/bench_season.py +0 -0
  28. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/benchmarks/bench_spatial.py +0 -0
  29. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/benchmarks/bench_view.py +0 -0
  30. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/benchmarks/run_all.sh +0 -0
  31. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/docs/Makefile +0 -0
  32. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/docs/make.bat +0 -0
  33. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/docs/source/concepts.md +0 -0
  34. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/docs/source/conf.py +0 -0
  35. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/docs/source/export.md +0 -0
  36. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/docs/source/index.rst +0 -0
  37. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/docs/source/intro.md +0 -0
  38. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/docs/source/logging.md +0 -0
  39. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/docs/source/plots.md +0 -0
  40. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/docs/source/plugins.md +0 -0
  41. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/docs/source/queries.md +0 -0
  42. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/docs/source/quickstart.md +0 -0
  43. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/docs/source/stats.md +0 -0
  44. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/examples/demo_mws.py +0 -0
  45. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/examples/demo_tehsil.py +0 -0
  46. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/hooks/mypy.sh +0 -0
  47. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/hooks/no-parquet-outside-fixtures.sh +0 -0
  48. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/hooks/pytest.sh +0 -0
  49. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/pyproject.toml +0 -0
  50. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/__init__.py +0 -0
  51. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/__main__.py +0 -0
  52. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/aoi.py +0 -0
  53. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/base/__init__.py +0 -0
  54. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/base/entity.py +0 -0
  55. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/base/namespaces/__init__.py +0 -0
  56. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/base/namespaces/plot.py +0 -0
  57. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/base/namespaces/stats.py +0 -0
  58. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/base/view.py +0 -0
  59. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/entities/__init__.py +0 -0
  60. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/entities/mws.py +0 -0
  61. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/entities/tehsil.py +0 -0
  62. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/entities/waterbody.py +0 -0
  63. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/export/__init__.py +0 -0
  64. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/export/formats.py +0 -0
  65. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/py.typed +0 -0
  66. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/schema/__init__.py +0 -0
  67. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/schema/detection.py +0 -0
  68. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/schema/profile.py +0 -0
  69. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/utils/__init__.py +0 -0
  70. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/utils/paths.py +0 -0
  71. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/utils/season.py +0 -0
  72. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/src/core_lens/utils/spatial.py +0 -0
  73. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/tests/fixtures/generate_fixtures.py +0 -0
  74. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/tests/unit/conftest.py +0 -0
  75. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/tests/unit/test_aoi.py +0 -0
  76. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/tests/unit/test_entities.py +0 -0
  77. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/tests/unit/test_entity.py +0 -0
  78. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/tests/unit/test_export.py +0 -0
  79. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/tests/unit/test_main.py +0 -0
  80. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/tests/unit/test_plot.py +0 -0
  81. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/tests/unit/test_polars_utils.py +0 -0
  82. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/tests/unit/test_profile.py +0 -0
  83. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/tests/unit/test_result.py +0 -0
  84. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/tests/unit/test_schema_detection.py +0 -0
  85. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/tests/unit/test_schema_profile.py +0 -0
  86. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/tests/unit/test_season.py +0 -0
  87. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/tests/unit/test_season_config.py +0 -0
  88. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/tests/unit/test_spatial.py +0 -0
  89. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/tests/unit/test_stats.py +0 -0
  90. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/tests/unit/test_view.py +0 -0
  91. {core_lens-0.1.dev148 → core_lens-0.1.dev150}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: core-lens
3
- Version: 0.1.dev148
3
+ Version: 0.1.dev150
4
4
  Summary: Query, analyse, and visualise CoreStack's microwatershed and Earth science data through a clean, composable Python API.
5
5
  Project-URL: Homepage, https://github.com/ApoorvaKashyap/core-lens
6
6
  Project-URL: Issues, https://github.com/ApoorvaKashyap/core-lens/issues
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.1.dev148'
22
- __version_tuple__ = version_tuple = (0, 1, 'dev148')
21
+ __version__ = version = '0.1.dev150'
22
+ __version_tuple__ = version_tuple = (0, 1, 'dev150')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -155,10 +155,13 @@ class Result:
155
155
  return self
156
156
 
157
157
  key_cols = self.key_cols
158
- geo_lf = self.entity.geometry_lazy.join(
159
- self.data.select(key_cols), on=key_cols, how="semi"
160
- )
161
- joined = self.data.join(geo_lf, on=key_cols, how="left")
158
+
159
+ # We use a direct left join here instead of a semi-join intermediate step.
160
+ # A semi-join creates a "diamond" query graph where `self.data` must be evaluated
161
+ # twice by Polars. Because `self.data` can be an expensive aggregation pipeline,
162
+ # this caused execution times to double.
163
+ joined = self.data.join(self.entity.geometry_lazy, on=key_cols, how="left")
164
+
162
165
  return self._replace(data=joined, has_geometry=True)
163
166
 
164
167
  def derive(self, name: str, expr: pl.Expr) -> "Result":
@@ -140,7 +140,15 @@ def scan_with_key_filter(
140
140
  if time_expr is not None:
141
141
  lf = lf.filter(time_expr)
142
142
 
143
- kv_lazy = key_values.lazy() if isinstance(key_values, pl.DataFrame) else key_values
144
- lf = lf.join(kv_lazy, on=key_cols, how="semi")
143
+ kv_df = key_values.collect() if isinstance(key_values, pl.LazyFrame) else key_values
144
+ if len(key_cols) == 1 and kv_df.height < 50000:
145
+ # Fast path: For reasonably sized AoIs, `is_in` enables perfect row-group
146
+ # predicate pushdown in the Parquet reader, avoiding a full table scan.
147
+ # The literal tree RAM issue only occurs with hundreds of thousands of keys.
148
+ key = key_cols[0]
149
+ lf = lf.filter(pl.col(key).is_in(kv_df[key]))
150
+ else:
151
+ # Fallback to semi-join for massive key arrays (e.g. state-wide scopes)
152
+ lf = lf.join(kv_df.lazy(), on=key_cols, how="semi")
145
153
 
146
154
  return lf
File without changes
File without changes
File without changes
File without changes