Skip to content

Commit 6411f5d

Browse files
committed
pygmt.blockm*: Add 'output_type' parameter for pandas/numpy/file outputs
1 parent bf7b9a1 commit 6411f5d

File tree

1 file changed

+104
-76
lines changed

1 file changed

+104
-76
lines changed

pygmt/src/blockm.py

Lines changed: 104 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,26 @@
11
"""
2-
blockm - Block average (x, y, z) data tables by mean, median, or mode
3-
estimation.
2+
blockm - Block average (x, y, z) data tables by mean, median, or mode estimation.
43
"""
54

5+
from typing import Literal
6+
7+
import numpy as np
68
import pandas as pd
79
from pygmt.clib import Session
810
from pygmt.helpers import (
9-
GMTTempFile,
1011
build_arg_string,
1112
fmt_docstring,
1213
kwargs_to_strings,
1314
use_alias,
15+
validate_output_table_type,
1416
)
1517

1618
__doctest_skip__ = ["blockmean", "blockmedian", "blockmode"]
1719

1820

19-
def _blockm(block_method, data, x, y, z, outfile, **kwargs):
21+
def _blockm(
22+
block_method, data, x, y, z, output_type, outfile, **kwargs
23+
) -> pd.DataFrame | np.ndarray | None:
2024
r"""
2125
Block average (x, y, z) data tables by mean, median, or mode estimation.
2226
@@ -34,38 +38,33 @@ def _blockm(block_method, data, x, y, z, outfile, **kwargs):
3438
3539
Returns
3640
-------
37-
output : pandas.DataFrame or None
38-
Return type depends on whether the ``outfile`` parameter is set:
41+
ret
42+
Return type depends on ``outfile`` and ``output_type``:
3943
40-
- :class:`pandas.DataFrame` table with (x, y, z) columns if ``outfile``
41-
is not set
42-
- None if ``outfile`` is set (filtered output will be stored in file
43-
set by ``outfile``)
44+
- None if ``outfile`` is set (output will be stored in file set by ``outfile``)
45+
- :class:`pandas.DataFrame` or :class:`numpy.ndarray` if ``outfile`` is not set
46+
(depends on ``output_type``)
4447
"""
45-
with GMTTempFile(suffix=".csv") as tmpfile:
46-
with Session() as lib:
47-
with lib.virtualfile_in(
48+
output_type = validate_output_table_type(output_type, outfile=outfile)
49+
50+
column_names = None
51+
if output_type == "pandas" and isinstance(data, pd.DataFrame):
52+
column_names = data.columns.to_list()
53+
54+
with Session() as lib:
55+
with (
56+
lib.virtualfile_in(
4857
check_kind="vector", data=data, x=x, y=y, z=z, required_z=True
49-
) as vintbl:
50-
# Run blockm* on data table
51-
if outfile is None:
52-
outfile = tmpfile.name
53-
lib.call_module(
54-
module=block_method,
55-
args=build_arg_string(kwargs, infile=vintbl, outfile=outfile),
56-
)
57-
58-
# Read temporary csv output to a pandas table
59-
if outfile == tmpfile.name: # if user did not set outfile, return pd.DataFrame
60-
try:
61-
column_names = data.columns.to_list()
62-
result = pd.read_csv(tmpfile.name, sep="\t", names=column_names)
63-
except AttributeError: # 'str' object has no attribute 'columns'
64-
result = pd.read_csv(tmpfile.name, sep="\t", header=None, comment=">")
65-
elif outfile != tmpfile.name: # return None if outfile set, output in outfile
66-
result = None
67-
68-
return result
58+
) as vintbl,
59+
lib.virtualfile_out(kind="dataset", fname=outfile) as vouttbl,
60+
):
61+
lib.call_module(
62+
module=block_method,
63+
args=build_arg_string(kwargs, infile=vintbl, outfile=vouttbl),
64+
)
65+
return lib.virtualfile_to_dataset(
66+
output_type=output_type, vfile=vouttbl, column_names=column_names
67+
)
6968

7069

7170
@fmt_docstring
@@ -86,7 +85,15 @@ def _blockm(block_method, data, x, y, z, outfile, **kwargs):
8685
w="wrap",
8786
)
8887
@kwargs_to_strings(I="sequence", R="sequence", i="sequence_comma", o="sequence_comma")
89-
def blockmean(data=None, x=None, y=None, z=None, outfile=None, **kwargs):
88+
def blockmean(
89+
data=None,
90+
x=None,
91+
y=None,
92+
z=None,
93+
output_type: Literal["pandas", "numpy", "file"] = "pandas",
94+
outfile: str | None = None,
95+
**kwargs,
96+
) -> pd.DataFrame | np.ndarray | None:
9097
r"""
9198
Block average (x, y, z) data tables by mean estimation.
9299
@@ -111,9 +118,9 @@ def blockmean(data=None, x=None, y=None, z=None, outfile=None, **kwargs):
111118
{table-classes}.
112119
x/y/z : 1-D arrays
113120
Arrays of x and y coordinates and values z of the data points.
114-
121+
{output_type}
122+
{outfile}
115123
{spacing}
116-
117124
summary : str
118125
[**m**\|\ **n**\|\ **s**\|\ **w**].
119126
Type of summary values calculated by blockmean.
@@ -122,12 +129,7 @@ def blockmean(data=None, x=None, y=None, z=None, outfile=None, **kwargs):
122129
- **n** - report the number of input points inside each block
123130
- **s** - report the sum of all z-values inside a block
124131
- **w** - report the sum of weights
125-
126132
{region}
127-
128-
outfile : str
129-
The file name for the output ASCII file.
130-
131133
{verbose}
132134
{aspatial}
133135
{binary}
@@ -142,13 +144,12 @@ def blockmean(data=None, x=None, y=None, z=None, outfile=None, **kwargs):
142144
143145
Returns
144146
-------
145-
output : pandas.DataFrame or None
146-
Return type depends on whether the ``outfile`` parameter is set:
147+
ret
148+
Return type depends on ``outfile`` and ``output_type``:
147149
148-
- :class:`pandas.DataFrame` table with (x, y, z) columns if ``outfile``
149-
is not set.
150-
- None if ``outfile`` is set (filtered output will be stored in file
151-
set by ``outfile``).
150+
- None if ``outfile`` is set (output will be stored in file set by ``outfile``)
151+
- :class:`pandas.DataFrame` or :class:`numpy.ndarray` if ``outfile`` is not set
152+
(depends on ``output_type``)
152153
153154
Example
154155
-------
@@ -159,7 +160,14 @@ def blockmean(data=None, x=None, y=None, z=None, outfile=None, **kwargs):
159160
>>> data_bmean = pygmt.blockmean(data=data, region=[245, 255, 20, 30], spacing="5m")
160161
"""
161162
return _blockm(
162-
block_method="blockmean", data=data, x=x, y=y, z=z, outfile=outfile, **kwargs
163+
block_method="blockmean",
164+
data=data,
165+
x=x,
166+
y=y,
167+
z=z,
168+
output_type=output_type,
169+
outfile=outfile,
170+
**kwargs,
163171
)
164172

165173

@@ -180,7 +188,15 @@ def blockmean(data=None, x=None, y=None, z=None, outfile=None, **kwargs):
180188
w="wrap",
181189
)
182190
@kwargs_to_strings(I="sequence", R="sequence", i="sequence_comma", o="sequence_comma")
183-
def blockmedian(data=None, x=None, y=None, z=None, outfile=None, **kwargs):
191+
def blockmedian(
192+
data=None,
193+
x=None,
194+
y=None,
195+
z=None,
196+
output_type: Literal["pandas", "numpy", "file"] = "pandas",
197+
outfile: str | None = None,
198+
**kwargs,
199+
) -> pd.DataFrame | np.ndarray | None:
184200
r"""
185201
Block average (x, y, z) data tables by median estimation.
186202
@@ -205,14 +221,10 @@ def blockmedian(data=None, x=None, y=None, z=None, outfile=None, **kwargs):
205221
{table-classes}.
206222
x/y/z : 1-D arrays
207223
Arrays of x and y coordinates and values z of the data points.
208-
224+
{output_type}
225+
{outfile}
209226
{spacing}
210-
211227
{region}
212-
213-
outfile : str
214-
The file name for the output ASCII file.
215-
216228
{verbose}
217229
{aspatial}
218230
{binary}
@@ -227,13 +239,12 @@ def blockmedian(data=None, x=None, y=None, z=None, outfile=None, **kwargs):
227239
228240
Returns
229241
-------
230-
output : pandas.DataFrame or None
231-
Return type depends on whether the ``outfile`` parameter is set:
242+
ret
243+
Return type depends on ``outfile`` and ``output_type``:
232244
233-
- :class:`pandas.DataFrame` table with (x, y, z) columns if ``outfile``
234-
is not set.
235-
- None if ``outfile`` is set (filtered output will be stored in file
236-
set by ``outfile``).
245+
- None if ``outfile`` is set (output will be stored in file set by ``outfile``)
246+
- :class:`pandas.DataFrame` or :class:`numpy.ndarray` if ``outfile`` is not set
247+
(depends on ``output_type``)
237248
238249
Example
239250
-------
@@ -246,7 +257,14 @@ def blockmedian(data=None, x=None, y=None, z=None, outfile=None, **kwargs):
246257
... )
247258
"""
248259
return _blockm(
249-
block_method="blockmedian", data=data, x=x, y=y, z=z, outfile=outfile, **kwargs
260+
block_method="blockmedian",
261+
data=data,
262+
x=x,
263+
y=y,
264+
z=z,
265+
output_type=output_type,
266+
outfile=outfile,
267+
**kwargs,
250268
)
251269

252270

@@ -267,7 +285,15 @@ def blockmedian(data=None, x=None, y=None, z=None, outfile=None, **kwargs):
267285
w="wrap",
268286
)
269287
@kwargs_to_strings(I="sequence", R="sequence", i="sequence_comma", o="sequence_comma")
270-
def blockmode(data=None, x=None, y=None, z=None, outfile=None, **kwargs):
288+
def blockmode(
289+
data=None,
290+
x=None,
291+
y=None,
292+
z=None,
293+
output_type: Literal["pandas", "numpy", "file"] = "pandas",
294+
outfile: str | None = None,
295+
**kwargs,
296+
) -> pd.DataFrame | np.ndarray | None:
271297
r"""
272298
Block average (x, y, z) data tables by mode estimation.
273299
@@ -292,14 +318,10 @@ def blockmode(data=None, x=None, y=None, z=None, outfile=None, **kwargs):
292318
{table-classes}.
293319
x/y/z : 1-D arrays
294320
Arrays of x and y coordinates and values z of the data points.
295-
321+
{output_type}
322+
{outfile}
296323
{spacing}
297-
298324
{region}
299-
300-
outfile : str
301-
The file name for the output ASCII file.
302-
303325
{verbose}
304326
{aspatial}
305327
{binary}
@@ -314,13 +336,12 @@ def blockmode(data=None, x=None, y=None, z=None, outfile=None, **kwargs):
314336
315337
Returns
316338
-------
317-
output : pandas.DataFrame or None
318-
Return type depends on whether the ``outfile`` parameter is set:
339+
ret
340+
Return type depends on ``outfile`` and ``output_type``:
319341
320-
- :class:`pandas.DataFrame` table with (x, y, z) columns if ``outfile``
321-
is not set.
322-
- None if ``outfile`` is set (filtered output will be stored in file
323-
set by ``outfile``).
342+
- None if ``outfile`` is set (output will be stored in file set by ``outfile``)
343+
- :class:`pandas.DataFrame` or :class:`numpy.ndarray` if ``outfile`` is not set
344+
(depends on ``output_type``)
324345
325346
Example
326347
-------
@@ -331,5 +352,12 @@ def blockmode(data=None, x=None, y=None, z=None, outfile=None, **kwargs):
331352
>>> data_bmode = pygmt.blockmode(data=data, region=[245, 255, 20, 30], spacing="5m")
332353
"""
333354
return _blockm(
334-
block_method="blockmode", data=data, x=x, y=y, z=z, outfile=outfile, **kwargs
355+
block_method="blockmode",
356+
data=data,
357+
x=x,
358+
y=y,
359+
z=z,
360+
output_type=output_type,
361+
outfile=outfile,
362+
**kwargs,
335363
)

0 commit comments

Comments
 (0)