geebeam 0.2.0__tar.gz → 0.2.2__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.
- {geebeam-0.2.0 → geebeam-0.2.2}/PKG-INFO +3 -3
- {geebeam-0.2.0 → geebeam-0.2.2}/README.md +2 -2
- {geebeam-0.2.0 → geebeam-0.2.2}/_version.py +2 -2
- {geebeam-0.2.0 → geebeam-0.2.2}/src/geebeam/pipeline.py +64 -25
- geebeam-0.2.2/src/geebeam/sampler.py +97 -0
- {geebeam-0.2.0 → geebeam-0.2.2}/src/geebeam/transforms.py +5 -5
- {geebeam-0.2.0 → geebeam-0.2.2}/tests/test_sampler.py +6 -7
- {geebeam-0.2.0 → geebeam-0.2.2}/tests/test_transforms.py +5 -5
- geebeam-0.2.0/src/geebeam/sampler.py +0 -52
- {geebeam-0.2.0 → geebeam-0.2.2}/.gitignore +0 -0
- {geebeam-0.2.0 → geebeam-0.2.2}/LICENSE +0 -0
- {geebeam-0.2.0 → geebeam-0.2.2}/pyproject.toml +0 -0
- {geebeam-0.2.0 → geebeam-0.2.2}/src/geebeam/__init__.py +0 -0
- {geebeam-0.2.0 → geebeam-0.2.2}/src/geebeam/climate_indices.py +0 -0
- {geebeam-0.2.0 → geebeam-0.2.2}/src/geebeam/ee_utils.py +0 -0
- {geebeam-0.2.0 → geebeam-0.2.2}/tests/test_climate_indices.py +0 -0
- {geebeam-0.2.0 → geebeam-0.2.2}/tests/test_ee_utils.py +0 -0
- {geebeam-0.2.0 → geebeam-0.2.2}/tests/test_pipeline.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: geebeam
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Earth Engine + Apache Beam
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -72,7 +72,7 @@ geebeam.run_pipeline(
|
|
|
72
72
|
scale=500, # Final export resolution in meters
|
|
73
73
|
n_sample=10, # Number of tiles to sample
|
|
74
74
|
validation_ratio=0.2, # Fraction to select as validation data
|
|
75
|
-
output_path='./
|
|
75
|
+
output_path='./test_tf_data/',
|
|
76
76
|
sampling_region=ee.Geometry.Rectangle(-63.0, -9.0, -56.0, -4.0)
|
|
77
77
|
)
|
|
78
78
|
```
|
|
@@ -95,7 +95,7 @@ geebeam.run_pipeline(
|
|
|
95
95
|
scale=500,
|
|
96
96
|
n_sample=10,
|
|
97
97
|
validation_ratio=0.2,
|
|
98
|
-
output_path='./
|
|
98
|
+
output_path='./test_tf_data/',
|
|
99
99
|
sampling_region=ee.Geometry.Rectangle(-63.0, -9.0, -56.0, -4.0),
|
|
100
100
|
num_workers=1
|
|
101
101
|
)
|
|
@@ -54,7 +54,7 @@ geebeam.run_pipeline(
|
|
|
54
54
|
scale=500, # Final export resolution in meters
|
|
55
55
|
n_sample=10, # Number of tiles to sample
|
|
56
56
|
validation_ratio=0.2, # Fraction to select as validation data
|
|
57
|
-
output_path='./
|
|
57
|
+
output_path='./test_tf_data/',
|
|
58
58
|
sampling_region=ee.Geometry.Rectangle(-63.0, -9.0, -56.0, -4.0)
|
|
59
59
|
)
|
|
60
60
|
```
|
|
@@ -77,7 +77,7 @@ geebeam.run_pipeline(
|
|
|
77
77
|
scale=500,
|
|
78
78
|
n_sample=10,
|
|
79
79
|
validation_ratio=0.2,
|
|
80
|
-
output_path='./
|
|
80
|
+
output_path='./test_tf_data/',
|
|
81
81
|
sampling_region=ee.Geometry.Rectangle(-63.0, -9.0, -56.0, -4.0),
|
|
82
82
|
num_workers=1
|
|
83
83
|
)
|
|
@@ -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.2.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 2,
|
|
21
|
+
__version__ = version = '0.2.2'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 2, 2)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
"""Prepare and run Beam pipeline to download image 'chips' from Earth Engine"""
|
|
2
|
+
|
|
3
|
+
import warnings
|
|
2
4
|
import ee
|
|
5
|
+
import geopandas as gpd
|
|
6
|
+
import pandas as pd
|
|
3
7
|
import numpy as np
|
|
4
8
|
import apache_beam as beam
|
|
5
9
|
from apache_beam.options.pipeline_options import PipelineOptions
|
|
@@ -11,9 +15,9 @@ from google.protobuf.json_format import MessageToJson
|
|
|
11
15
|
from geebeam import ee_utils, sampler, transforms
|
|
12
16
|
|
|
13
17
|
|
|
14
|
-
def _check_if_localrunner(
|
|
18
|
+
def _check_if_localrunner(pipeline_options):
|
|
15
19
|
"""Fixes gRPC timeout issue for local runners."""
|
|
16
|
-
runner =
|
|
20
|
+
runner = pipeline_options.get_all_options()['runner']
|
|
17
21
|
if runner is None or runner in ['DirectRunner', 'PrismRunner']:
|
|
18
22
|
return True
|
|
19
23
|
else:
|
|
@@ -32,29 +36,45 @@ def _prepare_run_metadata(config):
|
|
|
32
36
|
return scale_x, scale_y
|
|
33
37
|
|
|
34
38
|
def run_pipeline(
|
|
35
|
-
image_list,
|
|
36
|
-
|
|
37
|
-
output_path,
|
|
39
|
+
image_list: list[ee.Image],
|
|
40
|
+
output_path: str,
|
|
38
41
|
project: str,
|
|
39
42
|
patch_size: int,
|
|
40
43
|
scale: float,
|
|
41
44
|
n_sample: int,
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
sampling_region: str | gpd.GeoDataFrame | ee.Geometry | None = None,
|
|
46
|
+
sampling_points: pd.DataFrame | gpd.GeoDataFrame | ee.Geometry | None = None,
|
|
47
|
+
validation_ratio: float = 0.2,
|
|
48
|
+
crs: str = 'EPSG:4326',
|
|
49
|
+
random_seed: int = None,
|
|
50
|
+
split_processing: bool = False,
|
|
51
|
+
extra_metadata: dict = {},
|
|
52
|
+
beam_options: dict[str] | list[str] | None = None
|
|
53
|
+
) -> None:
|
|
54
|
+
"""Run a Beam pipeline to download image chips from Earth Engine.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
image_list: A list of image identifiers to process.
|
|
58
|
+
sampling_region: The region for sampling images.
|
|
59
|
+
sampling_points: Locations to sample from, specifying upper-left of box.
|
|
60
|
+
output_path: The path where output will be saved.
|
|
61
|
+
project: The Google Cloud project ID.
|
|
62
|
+
patch_size: The size of the patches to be processed.
|
|
63
|
+
scale: The scale factor for image processing.
|
|
64
|
+
n_sample: The number of samples to take.
|
|
65
|
+
validation_ratio: The ratio of data to use for validation. Defaults to 0.2.
|
|
66
|
+
crs: The coordinate reference system. Defaults to 'EPSG:4326'.
|
|
67
|
+
random_seed: Seed for random number generation. Defaults to None.
|
|
68
|
+
split_processing: Flag to indicate if processing should be split. Defaults to False.
|
|
69
|
+
extra_metadata: Additional metadata to include. Defaults to an empty dictionary.
|
|
70
|
+
beam_options_dict: Options for the Beam pipeline. Defaults to an empty dictionary.
|
|
71
|
+
"""
|
|
49
72
|
import logging
|
|
50
73
|
|
|
51
74
|
logging.getLogger().setLevel(logging.INFO)
|
|
52
75
|
|
|
53
76
|
rng = np.random.default_rng(random_seed)
|
|
54
77
|
|
|
55
|
-
# Parses from command line and/or retrieves from dict. Note that dict takes precedent.
|
|
56
|
-
beam_options = PipelineOptions(beam_options_dict)
|
|
57
|
-
|
|
58
78
|
# Set up configuration dict to pass along
|
|
59
79
|
config = {
|
|
60
80
|
'project_id': project,
|
|
@@ -65,9 +85,33 @@ def run_pipeline(
|
|
|
65
85
|
'crs': crs
|
|
66
86
|
}
|
|
67
87
|
|
|
68
|
-
#
|
|
69
|
-
|
|
70
|
-
|
|
88
|
+
# Parses from command line and/or retrieves from dict. Note that dict takes precedent.
|
|
89
|
+
if isinstance(beam_options, dict):
|
|
90
|
+
pipeline_options = PipelineOptions(
|
|
91
|
+
**beam_options,
|
|
92
|
+
project=config['project_id'],
|
|
93
|
+
save_main_session=True,
|
|
94
|
+
)
|
|
95
|
+
elif isinstance(beam_options, list):
|
|
96
|
+
warnings.warn('Creating PipelineOptions from beam_options list.'
|
|
97
|
+
' Ignores command-line beam options.')
|
|
98
|
+
pipeline_options = PipelineOptions(
|
|
99
|
+
beam_options,
|
|
100
|
+
project=config['project_id'],
|
|
101
|
+
save_main_session=True,
|
|
102
|
+
)
|
|
103
|
+
else:
|
|
104
|
+
pipeline_options = PipelineOptions(
|
|
105
|
+
project=config['project_id'],
|
|
106
|
+
save_main_session=True,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
# Get sample points
|
|
110
|
+
if sampling_points is not None:
|
|
111
|
+
sampled_points = sampler.process_sampling_points(sampling_points, target_crs=config['crs'])
|
|
112
|
+
else:
|
|
113
|
+
roi = sampler.get_roi(sampling_region, image_list, target_crs=config['crs'])
|
|
114
|
+
sampled_points = sampler.sample_random_points(roi, config['n_sample'], rng)
|
|
71
115
|
|
|
72
116
|
# Split into training and validation
|
|
73
117
|
input_records = sampler.split_train_validation(
|
|
@@ -78,14 +122,9 @@ def run_pipeline(
|
|
|
78
122
|
scale_x, scale_y = _prepare_run_metadata(config)
|
|
79
123
|
|
|
80
124
|
# Set up pipeline
|
|
81
|
-
beam_options = PipelineOptions(beam_options,
|
|
82
|
-
project=config['project_id'],
|
|
83
|
-
save_main_session=True,
|
|
84
|
-
use_public_ips=False
|
|
85
|
-
)
|
|
86
125
|
|
|
87
126
|
# Check if a local runner
|
|
88
|
-
is_local = _check_if_localrunner(
|
|
127
|
+
is_local = _check_if_localrunner(pipeline_options)
|
|
89
128
|
|
|
90
129
|
# Prepare and serialize inputs
|
|
91
130
|
# band_groups is a list of lists containing bands to export
|
|
@@ -95,7 +134,7 @@ def run_pipeline(
|
|
|
95
134
|
serialized_image = ee_utils.serialize(prepped_image)
|
|
96
135
|
|
|
97
136
|
# Execute pipeline
|
|
98
|
-
with beam.Pipeline(options=
|
|
137
|
+
with beam.Pipeline(options=pipeline_options) as pipeline:
|
|
99
138
|
|
|
100
139
|
points = pipeline | 'Create points' >> beam.Create(input_records)
|
|
101
140
|
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sample points from region of interest
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import warnings
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
import numpy as np
|
|
9
|
+
import pandas as pd
|
|
10
|
+
import geopandas as gpd
|
|
11
|
+
import ee
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_roi(
|
|
15
|
+
sampling_region: str | ee.Geometry | gpd.GeoDataFrame,
|
|
16
|
+
image_list: list[ee.Image],
|
|
17
|
+
target_crs: str
|
|
18
|
+
) -> gpd.GeoDataFrame:
|
|
19
|
+
|
|
20
|
+
if sampling_region is not None:
|
|
21
|
+
if isinstance(sampling_region, gpd.GeoDataFrame):
|
|
22
|
+
roi_df = sampling_region
|
|
23
|
+
elif isinstance(sampling_region, str):
|
|
24
|
+
roi_df = gpd.read_file(sampling_region)
|
|
25
|
+
elif isinstance(sampling_region, ee.Geometry):
|
|
26
|
+
# Looking for a better way to do this, this is silly
|
|
27
|
+
roi_df = gpd.read_file(json.dumps(sampling_region.getInfo()))
|
|
28
|
+
else:
|
|
29
|
+
raise ValueError("'sampling_region' must be one of"
|
|
30
|
+
"[str, ee.Geometry, gpd.GeoDataFrame]")
|
|
31
|
+
if roi_df.crs.to_string() != target_crs:
|
|
32
|
+
roi_df = roi_df.to_crs(target_crs)
|
|
33
|
+
return roi_df
|
|
34
|
+
else:
|
|
35
|
+
warnings.warn('Neither sampling_region nor sampling_points specified.\n'
|
|
36
|
+
'Defaulting to footprint of the first image in image_list.')
|
|
37
|
+
return image_list[0].geometry()
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def sample_random_points(roi: gpd.GeoDataFrame, n_sample: int, rng: np.random.Generator) -> pd.DataFrame:
|
|
41
|
+
"""Get random points within region of interest."""
|
|
42
|
+
sampled_points = roi.sample_points(n_sample, rng=rng).geometry.explode().get_coordinates()
|
|
43
|
+
sampled_points.index = np.arange(sampled_points.shape[0])
|
|
44
|
+
x = sampled_points.values[:,0]
|
|
45
|
+
y = sampled_points.values[:,1]
|
|
46
|
+
out_df = pd.DataFrame({
|
|
47
|
+
'y': y,
|
|
48
|
+
'x': x,
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
return out_df
|
|
52
|
+
|
|
53
|
+
def split_train_validation(points_df: pd.DataFrame, validation_ratio: float, rng: np.random.Generator, shuffle: bool = True):
|
|
54
|
+
# Shuffle order
|
|
55
|
+
points_df['split'] = 'train'
|
|
56
|
+
if shuffle:
|
|
57
|
+
points_df = points_df.sample(frac=1, random_state=rng).reset_index(drop=True)
|
|
58
|
+
points_df['id'] = points_df.index
|
|
59
|
+
|
|
60
|
+
# Split
|
|
61
|
+
num_train = round(points_df.shape[0]*(1-validation_ratio))
|
|
62
|
+
points_df.loc[num_train:, 'split'] = 'val'
|
|
63
|
+
|
|
64
|
+
return points_df
|
|
65
|
+
|
|
66
|
+
def process_sampling_points(
|
|
67
|
+
sampling_points: pd.DataFrame | ee.FeatureCollection | gpd.GeoDataFrame,
|
|
68
|
+
target_crs: str
|
|
69
|
+
) -> pd.DataFrame:
|
|
70
|
+
|
|
71
|
+
if isinstance(sampling_points, pd.DataFrame):
|
|
72
|
+
if 'x' not in sampling_points.columns or 'y' not in sampling_points.columns:
|
|
73
|
+
raise ValueError('If provided as pd.DataFrame, sampling_points must have columns '
|
|
74
|
+
'`x` and `y` with coordinates for sampling in target crs.')
|
|
75
|
+
points_df = sampling_points
|
|
76
|
+
elif isinstance(sampling_points, gpd.GeoDataFrame):
|
|
77
|
+
if sampling_points.crs != target_crs:
|
|
78
|
+
raise ValueError('sampling_points projection does not match target_crs.')
|
|
79
|
+
sampling_points['x'] = sampling_points.geometry.x
|
|
80
|
+
sampling_points['y'] = sampling_points.geometry.y
|
|
81
|
+
points_df = sampling_points
|
|
82
|
+
elif isinstance(sampling_points, ee.FeatureCollection):
|
|
83
|
+
fc_crs = sampling_points.first().geometry().projection().getInfo()
|
|
84
|
+
if fc_crs != target_crs:
|
|
85
|
+
raise ValueError('sampling_points projection does not match target_crs.')
|
|
86
|
+
points_df = ee.data.computeFeatures({
|
|
87
|
+
'expression': sampling_points,
|
|
88
|
+
'fileFormat': 'GEOPANDAS_GEODATAFRAME'
|
|
89
|
+
}
|
|
90
|
+
).set_crs(fc_crs)
|
|
91
|
+
points_df['x'] = points_df.geometry.x
|
|
92
|
+
points_df['y'] = points_df.geometry.y
|
|
93
|
+
else:
|
|
94
|
+
raise ValueError("'sampling_points' must be one of"
|
|
95
|
+
"[pd.DataFrame, gpd.GeoDataFrame, ee.FeatureCollection]")
|
|
96
|
+
|
|
97
|
+
return points_df
|
|
@@ -46,11 +46,11 @@ def dict_to_example(element):
|
|
|
46
46
|
# First add metadata
|
|
47
47
|
md_dict = {
|
|
48
48
|
'md_id': _int64_feature(element['metadata']['id']),
|
|
49
|
-
'
|
|
50
|
-
'
|
|
49
|
+
'md_y': _float_feature(element['metadata']['y']),
|
|
50
|
+
'md_x': _float_feature(element['metadata']['x']),
|
|
51
51
|
}
|
|
52
52
|
for md_key in element['metadata'].keys():
|
|
53
|
-
if md_key not in ['id','
|
|
53
|
+
if md_key not in ['id','y','x', 'split']:
|
|
54
54
|
md_dict['md_' + md_key] = tf.train.Feature(float_list=
|
|
55
55
|
tf.train.FloatList(
|
|
56
56
|
value = convert_to_iterable(element['metadata'][md_key])
|
|
@@ -133,10 +133,10 @@ class EEComputePatch(beam.DoFn):
|
|
|
133
133
|
'affineTransform': {
|
|
134
134
|
'scaleX': self.scale_x,
|
|
135
135
|
'shearX': 0,
|
|
136
|
-
'translateX': point['
|
|
136
|
+
'translateX': point['x'],
|
|
137
137
|
'shearY': 0,
|
|
138
138
|
'scaleY': self.scale_y,
|
|
139
|
-
'translateY': point['
|
|
139
|
+
'translateY': point['y']
|
|
140
140
|
},
|
|
141
141
|
'crsCode': 'EPSG:4326',
|
|
142
142
|
},
|
|
@@ -19,16 +19,15 @@ def test_sample_random_points():
|
|
|
19
19
|
|
|
20
20
|
assert isinstance(result, pd.DataFrame)
|
|
21
21
|
assert result.shape == (2, 2)
|
|
22
|
-
assert '
|
|
23
|
-
assert '
|
|
24
|
-
|
|
25
|
-
assert result.iloc[0]['
|
|
26
|
-
assert result.iloc[0]['lat'] == 50.0
|
|
22
|
+
assert 'y' in result.columns
|
|
23
|
+
assert 'x' in result.columns
|
|
24
|
+
assert result.iloc[0]['x'] == 10.0
|
|
25
|
+
assert result.iloc[0]['y'] == 50.0
|
|
27
26
|
|
|
28
27
|
def test_split_train_validation():
|
|
29
28
|
df = pd.DataFrame({
|
|
30
|
-
'
|
|
31
|
-
'
|
|
29
|
+
'y': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
|
|
30
|
+
'x': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
|
32
31
|
})
|
|
33
32
|
rng = np.random.default_rng(42)
|
|
34
33
|
|
|
@@ -13,8 +13,8 @@ def test_dict_to_example():
|
|
|
13
13
|
element = {
|
|
14
14
|
'metadata': {
|
|
15
15
|
'id': 1,
|
|
16
|
-
'
|
|
17
|
-
'
|
|
16
|
+
'y': 10.0,
|
|
17
|
+
'x': 20.0,
|
|
18
18
|
'extra': 0.5
|
|
19
19
|
},
|
|
20
20
|
'array': {
|
|
@@ -30,8 +30,8 @@ def test_dict_to_example():
|
|
|
30
30
|
|
|
31
31
|
features = example.features.feature
|
|
32
32
|
assert features['md_id'].int64_list.value[0] == 1
|
|
33
|
-
assert features['
|
|
34
|
-
assert features['
|
|
33
|
+
assert features['md_y'].float_list.value[0] == 10.0
|
|
34
|
+
assert features['md_x'].float_list.value[0] == 20.0
|
|
35
35
|
assert features['md_extra'].float_list.value[0] == 0.5
|
|
36
36
|
assert list(features['im_band1'].float_list.value) == [1.0, 2.0, 3.0, 4.0]
|
|
37
37
|
|
|
@@ -75,7 +75,7 @@ def test_ee_compute_patch(mock_from_json, mock_compute_pixels, mock_ee_init):
|
|
|
75
75
|
patch_fn = EEComputePatch(config, serialized_image, scale_x, scale_y, band_groups)
|
|
76
76
|
patch_fn.setup() # Initialize EE
|
|
77
77
|
|
|
78
|
-
point = {'id': 1, '
|
|
78
|
+
point = {'id': 1, 'y': 10.0, 'x': 20.0}
|
|
79
79
|
results = list(patch_fn.process(point))
|
|
80
80
|
print(results)
|
|
81
81
|
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Sample points from region of interest
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import json
|
|
6
|
-
import numpy as np
|
|
7
|
-
import pandas as pd
|
|
8
|
-
import geopandas as gpd
|
|
9
|
-
import ee
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def get_roi(
|
|
13
|
-
sampling_region: str | ee.Geometry | gpd.GeoDataFrame
|
|
14
|
-
) -> gpd.GeoDataFrame:
|
|
15
|
-
|
|
16
|
-
if isinstance(sampling_region, gpd.GeoDataFrame):
|
|
17
|
-
roi_df = sampling_region
|
|
18
|
-
elif isinstance(sampling_region, str):
|
|
19
|
-
roi_df = gpd.read_file(sampling_region)
|
|
20
|
-
elif isinstance(sampling_region, ee.Geometry):
|
|
21
|
-
# Looking for a better way to do this, this is silly
|
|
22
|
-
roi_df = gpd.read_file(json.dumps(sampling_region.getInfo()))
|
|
23
|
-
else:
|
|
24
|
-
raise ValueError("'sampling_region' must be one of"
|
|
25
|
-
"[str, ee.Geometry, gpd.GeoDataFrame]")
|
|
26
|
-
return roi_df
|
|
27
|
-
|
|
28
|
-
def sample_random_points(roi: gpd.GeoDataFrame, n_sample: int, rng: np.random.Generator)->pd.DataFrame:
|
|
29
|
-
"""Get random points within region of interest."""
|
|
30
|
-
sampled_points = roi.sample_points(n_sample, rng=rng).geometry.explode().get_coordinates()
|
|
31
|
-
sampled_points.index = np.arange(sampled_points.shape[0])
|
|
32
|
-
lon = sampled_points.values[:,0]
|
|
33
|
-
lat = sampled_points.values[:,1]
|
|
34
|
-
out_df = pd.DataFrame({
|
|
35
|
-
'lat': lat,
|
|
36
|
-
'lon': lon,
|
|
37
|
-
}
|
|
38
|
-
)
|
|
39
|
-
return out_df
|
|
40
|
-
|
|
41
|
-
def split_train_validation(points_df: pd.DataFrame, validation_ratio: float, rng: np.random.Generator, shuffle: bool = True):
|
|
42
|
-
# Shuffle order
|
|
43
|
-
points_df['split'] = 'train'
|
|
44
|
-
if shuffle:
|
|
45
|
-
points_df = points_df.sample(frac=1, random_state=rng).reset_index(drop=True)
|
|
46
|
-
points_df['id'] = points_df.index
|
|
47
|
-
|
|
48
|
-
# Split
|
|
49
|
-
num_train = round(points_df.shape[0]*(1-validation_ratio))
|
|
50
|
-
points_df.loc[num_train:, 'split'] = 'val'
|
|
51
|
-
|
|
52
|
-
return points_df
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|