well-log-toolkit 0.1.144__py3-none-any.whl → 0.1.145__py3-none-any.whl
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.
- well_log_toolkit/property.py +42 -19
- {well_log_toolkit-0.1.144.dist-info → well_log_toolkit-0.1.145.dist-info}/METADATA +1 -1
- {well_log_toolkit-0.1.144.dist-info → well_log_toolkit-0.1.145.dist-info}/RECORD +5 -5
- {well_log_toolkit-0.1.144.dist-info → well_log_toolkit-0.1.145.dist-info}/WHEEL +0 -0
- {well_log_toolkit-0.1.144.dist-info → well_log_toolkit-0.1.145.dist-info}/top_level.txt +0 -0
well_log_toolkit/property.py
CHANGED
|
@@ -1789,7 +1789,11 @@ class Property(PropertyOperationsMixin):
|
|
|
1789
1789
|
|
|
1790
1790
|
return result
|
|
1791
1791
|
|
|
1792
|
-
def discrete_summary(
|
|
1792
|
+
def discrete_summary(
|
|
1793
|
+
self,
|
|
1794
|
+
precision: int = 6,
|
|
1795
|
+
skip: Optional[list[str]] = None
|
|
1796
|
+
) -> dict:
|
|
1793
1797
|
"""
|
|
1794
1798
|
Compute summary statistics for discrete/categorical properties.
|
|
1795
1799
|
|
|
@@ -1801,6 +1805,9 @@ class Property(PropertyOperationsMixin):
|
|
|
1801
1805
|
----------
|
|
1802
1806
|
precision : int, default 6
|
|
1803
1807
|
Number of decimal places for rounding numeric results
|
|
1808
|
+
skip : list[str], optional
|
|
1809
|
+
List of field names to exclude from the output.
|
|
1810
|
+
Valid fields: 'code', 'count', 'thickness', 'fraction', 'depth_range'
|
|
1804
1811
|
|
|
1805
1812
|
Returns
|
|
1806
1813
|
-------
|
|
@@ -1808,8 +1815,7 @@ class Property(PropertyOperationsMixin):
|
|
|
1808
1815
|
Nested dictionary with statistics for each discrete value.
|
|
1809
1816
|
If secondary properties (filters) exist, the structure is hierarchical.
|
|
1810
1817
|
|
|
1811
|
-
For each discrete value, includes:
|
|
1812
|
-
- label: Human-readable name (if labels defined)
|
|
1818
|
+
For each discrete value, includes (unless skipped):
|
|
1813
1819
|
- code: Numeric code for this category
|
|
1814
1820
|
- count: Number of samples with this value
|
|
1815
1821
|
- thickness: Total depth interval (meters) for this category
|
|
@@ -1824,6 +1830,10 @@ class Property(PropertyOperationsMixin):
|
|
|
1824
1830
|
>>> # {'Sand': {'code': 1, 'count': 150, 'thickness': 25.5, 'fraction': 0.45, ...},
|
|
1825
1831
|
>>> # 'Shale': {'code': 2, 'count': 180, 'thickness': 30.8, 'fraction': 0.55, ...}}
|
|
1826
1832
|
|
|
1833
|
+
>>> # Skip certain fields
|
|
1834
|
+
>>> stats = facies.discrete_summary(skip=['code', 'count'])
|
|
1835
|
+
>>> # {'Sand': {'thickness': 25.5, 'fraction': 0.45}, ...}
|
|
1836
|
+
|
|
1827
1837
|
>>> # Grouped by zones
|
|
1828
1838
|
>>> filtered = facies.filter('Well_Tops')
|
|
1829
1839
|
>>> stats = filtered.discrete_summary()
|
|
@@ -1842,26 +1852,43 @@ class Property(PropertyOperationsMixin):
|
|
|
1842
1852
|
# Check for custom intervals (from filter_intervals)
|
|
1843
1853
|
# These are processed independently, allowing overlaps
|
|
1844
1854
|
if hasattr(self, '_custom_intervals') and self._custom_intervals:
|
|
1845
|
-
|
|
1855
|
+
result = self._compute_discrete_stats_by_intervals(
|
|
1846
1856
|
gross_thickness=gross_thickness,
|
|
1847
1857
|
precision=precision
|
|
1848
1858
|
)
|
|
1849
|
-
|
|
1850
|
-
if not self.secondary_properties:
|
|
1859
|
+
elif not self.secondary_properties:
|
|
1851
1860
|
# No filters, compute stats for all discrete values
|
|
1852
|
-
|
|
1861
|
+
result = self._compute_discrete_stats(
|
|
1862
|
+
np.ones(len(self.depth), dtype=bool),
|
|
1863
|
+
gross_thickness=gross_thickness,
|
|
1864
|
+
precision=precision
|
|
1865
|
+
)
|
|
1866
|
+
else:
|
|
1867
|
+
# Build hierarchical grouping
|
|
1868
|
+
result = self._recursive_discrete_group(
|
|
1869
|
+
0,
|
|
1853
1870
|
np.ones(len(self.depth), dtype=bool),
|
|
1854
1871
|
gross_thickness=gross_thickness,
|
|
1855
1872
|
precision=precision
|
|
1856
1873
|
)
|
|
1857
1874
|
|
|
1858
|
-
#
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1875
|
+
# Remove skipped fields from output
|
|
1876
|
+
if skip:
|
|
1877
|
+
result = self._remove_keys_recursive(result, skip)
|
|
1878
|
+
|
|
1879
|
+
return result
|
|
1880
|
+
|
|
1881
|
+
def _remove_keys_recursive(self, d: dict, keys_to_remove: list[str]) -> dict:
|
|
1882
|
+
"""Recursively remove specified keys from nested dicts."""
|
|
1883
|
+
result = {}
|
|
1884
|
+
for key, value in d.items():
|
|
1885
|
+
if key in keys_to_remove:
|
|
1886
|
+
continue
|
|
1887
|
+
if isinstance(value, dict):
|
|
1888
|
+
result[key] = self._remove_keys_recursive(value, keys_to_remove)
|
|
1889
|
+
else:
|
|
1890
|
+
result[key] = value
|
|
1891
|
+
return result
|
|
1865
1892
|
|
|
1866
1893
|
def _compute_discrete_stats_by_intervals(
|
|
1867
1894
|
self,
|
|
@@ -2071,14 +2098,12 @@ class Property(PropertyOperationsMixin):
|
|
|
2071
2098
|
count = int(np.sum(val_mask))
|
|
2072
2099
|
fraction = thickness / gross_thickness if gross_thickness > 0 else 0.0
|
|
2073
2100
|
|
|
2074
|
-
# Determine the key
|
|
2101
|
+
# Determine the key (use label if available, otherwise name_code)
|
|
2075
2102
|
int_val = int(val)
|
|
2076
2103
|
if self.labels is not None and int_val in self.labels:
|
|
2077
2104
|
key = self.labels[int_val]
|
|
2078
|
-
label = self.labels[int_val]
|
|
2079
2105
|
else:
|
|
2080
2106
|
key = f"{self.name}_{int_val}"
|
|
2081
|
-
label = None
|
|
2082
2107
|
|
|
2083
2108
|
stats = {
|
|
2084
2109
|
'code': int_val,
|
|
@@ -2091,8 +2116,6 @@ class Property(PropertyOperationsMixin):
|
|
|
2091
2116
|
'min': round(float(np.min(val_depths)), precision),
|
|
2092
2117
|
'max': round(float(np.max(val_depths)), precision)
|
|
2093
2118
|
}
|
|
2094
|
-
if label is not None:
|
|
2095
|
-
stats['label'] = label
|
|
2096
2119
|
|
|
2097
2120
|
result[key] = stats
|
|
2098
2121
|
|
|
@@ -3,13 +3,13 @@ well_log_toolkit/exceptions.py,sha256=X_fzC7d4yaBFO9Vx74dEIB6xmI9Agi6_bTU3MPxn6k
|
|
|
3
3
|
well_log_toolkit/las_file.py,sha256=Tj0mRfX1aX2s6uug7BBlY1m_mu3G50EGxHGzD0eEedE,53876
|
|
4
4
|
well_log_toolkit/manager.py,sha256=VIARJLkYhxqxgTqfVfAAZU6AVsAPkQWPOUE6RNGnIdY,110558
|
|
5
5
|
well_log_toolkit/operations.py,sha256=z8j8fGBOwoJGUQFy-Vawjq9nm3OD_dUt0oaNh8yuG7o,18515
|
|
6
|
-
well_log_toolkit/property.py,sha256=
|
|
6
|
+
well_log_toolkit/property.py,sha256=O5Ti5ahWV3CTlBLGZ-ntEIed6GGyzsxnyO_EbYrNLP0,100752
|
|
7
7
|
well_log_toolkit/regression.py,sha256=JDcRxaODJnFikAdPJyTq8eUV7iY0vCDmvnGufqlojxs,31625
|
|
8
8
|
well_log_toolkit/statistics.py,sha256=_huPMbv2H3o9ezunjEM94mJknX5wPK8V4nDv2lIZZRw,16814
|
|
9
9
|
well_log_toolkit/utils.py,sha256=O2KPq4htIoUlL74V2zKftdqqTjRfezU9M-568zPLme0,6866
|
|
10
10
|
well_log_toolkit/visualization.py,sha256=nnpmFmbj44TbP0fsnLMR1GaKRkqKCEpI6Fd8Cp0oqBc,204716
|
|
11
11
|
well_log_toolkit/well.py,sha256=n6XfaGSjGtyXCIaAr0ytslIK0DMUY_fSPQ_VCqj8jaU,106173
|
|
12
|
-
well_log_toolkit-0.1.
|
|
13
|
-
well_log_toolkit-0.1.
|
|
14
|
-
well_log_toolkit-0.1.
|
|
15
|
-
well_log_toolkit-0.1.
|
|
12
|
+
well_log_toolkit-0.1.145.dist-info/METADATA,sha256=5HaBS3lhnirT8Uu8SEvjFn60HRdG8Ft5sa-DUhl94yU,63473
|
|
13
|
+
well_log_toolkit-0.1.145.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
14
|
+
well_log_toolkit-0.1.145.dist-info/top_level.txt,sha256=BMOo7OKLcZEnjo0wOLMclwzwTbYKYh31I8RGDOGSBdE,17
|
|
15
|
+
well_log_toolkit-0.1.145.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|