imod.ipf - IPF file I/O¶
Functions for reading and writing iMOD Point Files (IDFs) to pandas.DataFrame
.
The primary functions to use are imod.ipf.read()
and
imod.ipf.save()
, though lower level functions are also available.
-
imod.ipf.
read
(path, kwargs={}, assoc_kwargs={})[source]¶ Read one or more IPF files to a single pandas.DataFrame, including associated (TXT) files.
The different IPF files can be from different model layers, and column names may differ between them.
Note that this function always returns a
pandas.DataFrame
. IPF files always contain spatial information, for whichgeopandas.GeoDataFrame
is a better fit, in principle. However, GeoDataFrames are not the best fit for the associated data.To perform spatial operations on the points, you’re likely best served by (temporarily) creating a GeoDataFrame, doing the spatial operation, and then using the output to select values in the original DataFrame. Please refer to the examples.
- Parameters
path (pathlib.Path or str) – globpath for IPF files to read.
kwargs (dict) – Dictionary containing the
pandas.read_csv()
keyword arguments for the IPF files (e.g. {“delim_whitespace”: True})assoc_kwargs (dict) – Dictionary containing the
pandas.read_csv()
keyword arguments for the associated (TXT) files (e.g. {“delim_whitespace”: True})
- Returns
- Return type
pandas.DataFrame
Examples
Read an IPF file into a dataframe:
>>> import imod >>> df = imod.ipf.read("example.ipf")
Convert the x and y data into a GeoDataFrame, do a spatial operation, and use it to select points within a polygon. Note:
gpd.points_from_xy()
requires a geopandas version >= 0.5.>>> import geopandas as gpd >>> polygon = gpd.read_file("polygon.shp").geometry[0] >>> ipf_points = gpd.GeoDataFrame(geometry=gpd.points_from_xy(df["x"], df["y"])) >>> within_polygon = ipf_points.within(polygon) >>> selection = df[within_polygon]
The same exercise is a little more complicated when associated files (like timeseries) are involved, since many duplicate values of x and y will exist. The easiest way to isolate these is by applying a groupby, and then taking first of x and y of every group:
>>> df = imod.ipf.read("example_with_time.ipf") >>> first = df.groupby("id").first() # replace "id" by what your ID column is called >>> x = first["x"] >>> y = first["y"] >>> id_code = first.index # id is a reserved keyword in python >>> ipf_points = gpd.GeoDataFrame(geometry=gpd.points_from_xy(x, y)) >>> within_polygon = ipf_points.within(polygon)
Using the result is a little more complicated as well, since it has to be mapped back to many duplicate values of the original dataframe. There are two options. First, by using the index:
>>> within_polygon.index = id_code >>> df = df.set_index("id") >>> selection = df[within_polygon]
If you do not wish to change index on the original dataframe, use
pandas.DataFrame.merge()
instead.>>> import pandas as pd >>> within_polygon = pd.DataFrame({"within": within_polygon}) >>> within_polygon["id"] = id_code >>> df = df.merge(within_polygon, on="id") >>> df = df[df["within"]]
-
imod.ipf.
read_associated
(path, kwargs={})[source]¶ Read an IPF associated file (TXT).
- Parameters
path (pathlib.Path or str) – Path to associated file.
kwargs (dict) – Dictionary containing the
pandas.read_csv()
keyword arguments for the associated (TXT) file (e.g. {“delim_whitespace”: True}).
- Returns
- Return type
pandas.DataFrame
-
imod.ipf.
save
(path, df, itype=None, assoc_ext='txt', nodata=1e+20, assoc_columns=None)[source]¶ Saves the contents of a pandas DataFrame to one or more IPF files, and associated (TXT) files.
Can write multiple IPF files if one of the columns is named “layer”. In turn, multiple associated (TXT) files may written for each of these IPF files.
- Parameters
path (pathlib.Path or str) – path of the written IPF file. Any associated files are written relative to this path, based on the ID column.
df (pandas.DataFrame) – DataFrame containing the data to write.
itype (int or str or None) –
IPF type. Defaults to
None
, in which case no associated files are created. Possible other values, either integer or string:1
or"timeseries"
2
or"borehole1d"
3
or"cpt"
4
or"borehole3d"
assoc_ext (str) – Extension of the associated files. Defaults to “txt”.
nodata (float) – The value given to nodata values. These are generally NaN (Not-a-Number) in pandas, but this leads to errors in iMOD(FLOW) for IDFs. Defaults to value of 1.0e20 instead.
assoc_columns (optional, list or dict) – Columns to store in the associated file. In case of a dictionary, the columns will be renamed according to the mapping in the dictionary. Defaults to None.
- Returns
Writes files.
- Return type
None
-
imod.ipf.
write
(path, df, indexcolumn=0, assoc_ext='txt', nodata=1e+20)[source]¶ Writes a single IPF file.
- Parameters
path (pathlib.Path or str) – path of the written IPF file. Any associated files are written relative to this path, based on the ID column.
df (pandas.DataFrame) – DataFrame containing the data to write.
indexcolumn (integer) – number of the column containg the paths to the associated (TXT) files. Defaults to a value of 0 (no associated files).
assoc_ext (str) – Extension of the associated files. Defaults to “txt”.
- Returns
Writes a file.
- Return type
None
-
imod.ipf.
write_assoc
(path, df, itype=1, nodata=1e+20, assoc_columns=None)[source]¶ Writes a single IPF associated (TXT) file.
- Parameters
path (pathlib.Path or str) – Path for the written associated file.
df (pandas.DataFrame) – DataFrame containing the data to write.
itype (int or str) –
IPF type. Possible values, either integer or string:
1 : “timeseries” 2 : “borehole1d” 3 : “cpt” 4 : “borehole3d”
nodata (float) – The value given to nodata values. These are generally NaN (Not-a-Number) in pandas, but this leads to errors in iMOD(FLOW) for IDFs. Defaults to value of 1.0e20 instead.
assoc_columns (optional, list or dict) – Columns to store in the associated file. In case of a dictionary, the columns will be renamed according to the mapping in the dictionary. Defaults to None.
- Returns
Writes a file.
- Return type
None