From d343edfad8d9e6b72ebc6b1e92867d8fd1a7acb8 Mon Sep 17 00:00:00 2001 From: veenstrajelmer <60435591+veenstrajelmer@users.noreply.github.com> Date: Mon, 8 Apr 2024 15:31:43 +0200 Subject: [PATCH] added dataframe_to_xarray function (#86) * dataframe_to_xarray function * added testcase * updated docs * updated history.rst * added dataframe_to_xarray to measurement jupyter notebook --- HISTORY.rst | 1 + ddlpy/__init__.py | 4 +- ddlpy/ddlpy.py | 21 -- ddlpy/utils.py | 101 ++++++ docs/modules.rst | 1 + notebooks/measurements.ipynb | 579 +++++++++++++++++++++++++++++++---- tests/test_ddlpy.py | 48 ++- 7 files changed, 668 insertions(+), 87 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index d934575..64b14f0 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -6,6 +6,7 @@ UNRELEASED ------------------ * added `catalog_filter` argument to `ddlpy.locations()` to enabling retrieving the extended catalog in https://github.com/Deltares/ddlpy/pull/87 * pass all Code parameters to measurements request instead of only four in https://github.com/Deltares/ddlpy/pull/88 +* added ddlpy.dataframe_to_xarray()` function in https://github.com/Deltares/ddlpy/pull/86 0.3.0 (2023-03-13) ------------------ diff --git a/ddlpy/__init__.py b/ddlpy/__init__.py index b0b7212..36d851e 100644 --- a/ddlpy/__init__.py +++ b/ddlpy/__init__.py @@ -11,8 +11,9 @@ measurements_latest, measurements_available, measurements_amount, - simplify_dataframe, ) +from ddlpy.utils import (simplify_dataframe, + dataframe_to_xarray) __all__ = ['locations', 'measurements', @@ -20,4 +21,5 @@ 'measurements_available', 'measurements_amount', 'simplify_dataframe', + 'dataframe_to_xarray' ] diff --git a/ddlpy/ddlpy.py b/ddlpy/ddlpy.py index 9429f06..143ed4a 100644 --- a/ddlpy/ddlpy.py +++ b/ddlpy/ddlpy.py @@ -401,24 +401,3 @@ def measurements_latest(location): if result['Succesvol']: df = _combine_waarnemingenlijst(result, location) return df - - -def simplify_dataframe(df: pd.DataFrame): - """ - drop columns with constant values from the dataframe - and collect them in a dictionary which is - added as attrs of the dataframe - """ - - bool_constant = (df == df.iloc[0]).all() - - # constant columns are flattened and converted to dict of attrs - df_attrs = df.loc[:, bool_constant].iloc[0].to_dict() - - # varying columns are kept in output dataframe - df_simple = df.loc[:, ~bool_constant] - - # attach as attrs to dataframe - df_simple.attrs = df_attrs - - return df_simple diff --git a/ddlpy/utils.py b/ddlpy/utils.py index e7b6d0a..a14f123 100644 --- a/ddlpy/utils.py +++ b/ddlpy/utils.py @@ -1,5 +1,7 @@ import dateutil.rrule import itertools +import pandas as pd + def date_series(start, end, freq=dateutil.rrule.MONTHLY): """return a list of start and end date over the timespan start[->end following the frequency rule""" @@ -26,3 +28,102 @@ def pairwise(it): # remove it del result[-1] return result + + +def simplify_dataframe(df: pd.DataFrame): + """ + Drop columns with constant values from the dataframe and collect them + in a dictionary which is added as attrs of the dataframe. + """ + + bool_constant = (df == df.iloc[0]).all() + + # constant columns are flattened and converted to dict of attrs + df_attrs = df.loc[:, bool_constant].iloc[0].to_dict() + + # varying columns are kept in output dataframe + df_simple = df.loc[:, ~bool_constant].copy() + + # attach as attrs to dataframe + df_simple.attrs = df_attrs + + return df_simple + + +def code_description_attrs_from_dataframe(df: pd.DataFrame): + # create var_attrs_dict + colname_code_list = df.columns[df.columns.str.contains(".Code")] + var_attrs_dict = {} + for colname_code in colname_code_list: + colname_oms = colname_code.replace(".Code",".Omschrijving") + meas_twocol = df[[colname_code,colname_oms]].drop_duplicates() + attr_dict = meas_twocol.set_index(colname_code)[colname_oms].to_dict() + var_attrs_dict[colname_code] = attr_dict + return var_attrs_dict + + +def dataframe_to_xarray(df: pd.DataFrame, drop_if_constant=[]): + """ + Converts the measurement dataframe to a xarray dataset, + including several cleanups to minimize the size of the netcdf dataset on disk: + + - The column 'Parameter_Wat_Omschrijving' is dropped (combination of information in other columns) + - The column 'Meetwaarde.Waarde_Alfanumeriek' is dropped if 'Meetwaarde.Waarde_Numeriek' is present (contains duplicate values in that case) + - All Omschrijving columns are dropped and added as attributes to the Code variables + - All NVT-only Code columns are dropped and added as ds attributes + - All location columns are dropped and added as ds attributes + - All drop_if_constant columns are dropped and added as ds attributes (if the values are indeed constant) + + """ + + # create list of columns with duplicate info (often not constant), will be dropped + cols_bulky = ["Parameter_Wat_Omschrijving"] + if "Meetwaarde.Waarde_Alfanumeriek" in df.columns and 'Meetwaarde.Waarde_Numeriek' in df.columns: + # drop alfanumeriek if duplicate of numeriek # TODO: should not be returned by ddl + cols_bulky.append("Meetwaarde.Waarde_Alfanumeriek") + + # create list of all omschrijving columns, will be dropped (added as ds[varn].attrs via code_description_attrs_from_dataframe()) + cols_omschrijving = df.columns[df.columns.str.contains(".Omschrijving")].tolist() + + # create list of all-NVT *.Code columns, will be dropped (codes added as ds.attrs) + bool_onlynvt_code = (df=='NVT').all(axis=0) + cols_onlynvt_code = df.columns[bool_onlynvt_code].tolist() + cols_onlynvt_code = [x for x in cols_onlynvt_code if x.endswith(".Code")] + + # create list of location columns, will be dropped (added as ds.attrs) + cols_location = ['Code', 'Naam', 'Coordinatenstelsel', 'X', 'Y'] + + # add drop_if_constant colums to list if values are indeed constant, will be dropped (added as ds.attrs) + cols_constant = [] + for colname in drop_if_constant: + assert colname in df.columns + if len(df[colname].drop_duplicates()) == 1: + cols_constant.append(colname) + + # create ds attrs for all nvt/location/constant columns + ds_attrs = {} + attrs_columns = cols_onlynvt_code + cols_constant + cols_location + for colname in attrs_columns: + ds_attrs[colname] = df[colname].iloc[0] + + # drop columns + drop_columns = (cols_bulky + cols_location + cols_constant + + cols_onlynvt_code + cols_omschrijving) + df_simple = df.drop(drop_columns, axis=1, errors='ignore') + + # convert to UTC to please xarray + # TODO: adding tzone to time.encoding['units'] raises "ValueError: invalid time units: 1970-01-01 00:00:00 +01:00" + df_simple.index = df_simple.index.tz_convert(None) + + # convert to xarray dataset and add ds_attrs + ds = df_simple.to_xarray() + ds = ds.assign_attrs(ds_attrs) + + # assign attrs with code+omschrijving to each *.Code variable + var_attrs_dict = code_description_attrs_from_dataframe(df) + for varn in ds.data_vars: + if varn in var_attrs_dict.keys(): + var_attrs = var_attrs_dict[varn] + ds[varn] = ds[varn].assign_attrs(var_attrs) + + return ds diff --git a/docs/modules.rst b/docs/modules.rst index f98de20..bba1f43 100644 --- a/docs/modules.rst +++ b/docs/modules.rst @@ -17,3 +17,4 @@ ddlpy module :members: :undoc-members: :show-inheritance: + :member-order: bysource diff --git a/notebooks/measurements.ipynb b/notebooks/measurements.ipynb index 44e7469..d9d5df6 100644 --- a/notebooks/measurements.ipynb +++ b/notebooks/measurements.ipynb @@ -341,7 +341,7 @@ { "data": { "text/plain": [ - "[]" + "[]" ] }, "execution_count": 5, @@ -350,7 +350,7 @@ }, { "data": { - "image/png": "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AAAgmWABAAAASCZYAAAAAJIJFgAAAIBkggUAAAAgmWABAAAASCZYAAAAAJIJFgAAAIBkggUAAAAgmWABAAAASCZYAAAAAJIJFgAAAIBkggUAAAAgmWABAAAASCZYAAAAAJIJFgAAAIBkggUAAAAgmWABAAAASCZYAAAAAJIJFgAAAIBkggUAAAAgmWABAAAASCZYAAAAAJIlBQs333xzHHDAATFq1Kg49thjY+XKlX1dFwAAADAI5B0s3HnnnXH55ZfH1VdfHU8//XTMmDEjTj311HjzzTcLUR8AMAjU1dXFWWedFXV1df1dCgBQZLksy7J8nnDsscfGzJkz4x//8R8jIqK5uTmqq6vjC1/4Qlx55ZW7fX5DQ0NUVlbGli1boqKiIq1qAGDAmDZtWqxbt67146lTp8batWv7sSIAoLfy6bvnNWJh+/btsXr16jj55JP/cIKSkjj55JPjySefTKsWABi06urq2oUKERHr1q0zcgEAhpG8goX//u//jqampth3333bte+7776xcePGTp/T2NgYDQ0N7R4AwNBwzz33dNp+3333FbkSAKC/FHxXiOuuuy4qKytbH9XV1YW+JABQJOecc06n7WeddVaRKwEA+ktewcI+++wTpaWl8dvf/rZd+29/+9uYOHFip8+56qqrYsuWLa2PDRs2pFcLAAwoCxYsiKlTp7Zrmzp1aixYsKB/CgIAii6vYGHkyJFxzDHHxKOPPtra1tzcHI8++mgcd9xxnT6nvLw8Kioq2j0AgKFj7dq1UVtbG2effXbU1tZauBEAhpm8d4W48847o6amJm699daYNWtW3HTTTfF//+//jRdeeKHD2gudsSsEAAAADGz59N3L8j35/PnzY9OmTfF3f/d3sXHjxjjqqKPioYce6lGoAAAAAAwteY9Y6C0jFgAAAGBgy6fvXvBdIQAAAIChS7AAAAAAJBMsAAAAAMkECwAAAEAywQIAAACQTLAAAAAAJBMsAAAAAMkECwAAAEAywQIAAACQTLAAAAAAJBMsAAAAAMkECwAAAEAywQIAAACQTLAAAAAAJBMsAAAAAMkECwAAAEAywQIAAACQTLAAAAAAJBMsAAAAAMkECwAAAECysmJfMMuyiIhoaGgo9qUBAACAHmjps7f04btT9GDh3XffjYiI6urqYl8aAAAAyMO7774blZWV3R6Ty3oSP/Sh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4447rsPxhx56aDz77LPxi1/8ovVx5plntq5iW11dXczy6YF873Fnmpqa4tlnn41JkyYVqkx6IeUez549O9auXdsaDEZEvPTSSzFp0iShwgDVm5/lu+66KxobG+OCCy4odJn0Qso9/t3vftchPGgJDLMsK1yxJOnNz/GoUaNiv/32i507d8YPfvCDOOusswpdLkVy3HHHtXtNREQ88sgjPf47DehGf68eOZwsW7YsKy8vz+rq6rJf//rX2Wc/+9nsfe97X7Zx48Ysy7LswgsvzK688soun29XiIEv33t8zTXXZA8//HC2bt26bPXq1dn555+fjRo1KvvVr37VX18Cu5HvPX711VezMWPGZJdeemn24osvZg888EA2YcKE7Ktf/Wp/fQn0QOrv6zlz5mTz588vdrkkyPceX3311dmYMWOy733ve9nLL7+cLV++PJs6dWr28Y9/vL++BHYj33v885//PPvBD36QrVu3Lnv88cezk046KTvwwAOzt99+u5++Anbn3XffzZ555pnsmWeeySIiW7x4cfbMM89kr7zySpZlWXbllVdmF154YevxL7/8crbnnntmf/VXf5U9//zz2c0335yVlpZmDz30UH99CfRAvvc5y7LW44855pjsE5/4RPbMM8/4+7rABAtF9u1vfzvbf//9s5EjR2azZs3Kfv7zn7d+7oQTTshqamq6fK5gYXDI5x4vWrSo9dh99903+9jHPpY9/fTT/VA1+cj35/hnP/tZduyxx2bl5eXZQQcdlH3ta1/Ldu7cWeSqyVe+9/mFF17IIiJbvnx5kSslVT73eMeOHdlXvvKVbOrUqdmoUaOy6urq7C/+4i90Oge4fO7xY489lh122GFZeXl5Nm7cuOzCCy/MXnvttX6omp5asWJFFhEdHi33taamJjvhhBM6POeoo47KRo4cmR100EFZbW1t0esmPyn3ubPjp0yZUvTah5Nclhm/BwAAAKSxxgIAAACQTLAAAAAAJBMsAAAAAMkECwAAAEAywQIAAACQTLAAAAAAJBMsAAAAAMkECwAAADDIPP7443HGGWfE5MmTI5fLxb333pv3ObIsi+uvvz4OPvjgKC8vj/322y++9rWv5X2esryfAQAAAPSrbdu2xYwZM+Kiiy6Kc889N+kcl112WSxfvjyuv/76OOKII2Lz5s2xefPmvM+Ty7IsS6oAAAAA6He5XC7uueeeOPvss1vbGhsb48tf/nJ873vfi3feeScOP/zw+OY3vxnz5s2LiIjnn38+jjzyyHjuuefikEMO6dX1TYUAAACAIebSSy+NJ598MpYtWxb/9V//Feedd1589KMfjTVr1kRExP333x8HHXRQPPDAA3HggQfGAQccEJdccknSiAXBAgAAAAwhr776atTW1sZdd90Vc+fOjalTp8YVV1wRc+bMidra2oiIePnll+OVV16Ju+66K+64446oq6uL1atXx5/+6Z/mfT1rLAAAAMAQ8uyzz0ZTU1McfPDB7dobGxtj3LhxERHR3NwcjY2Ncccdd7Qet3Tp0jjmmGPixRdfzGt6hGABAAAAhpCtW7dGaWlprF69OkpLS9t9bvTo0RERMWnSpCgrK2sXPhx22GER8d6IB8ECAAAADFNHH310NDU1xZtvvhlz587t9JjZs2fHzp07Y926dTF16tSIiHjppZciImLKlCl5Xc+uEAAAADDIbN26NdauXRsR7wUJixcvjhNPPDHGjh0b+++/f1xwwQXxxBNPxA033BBHH310bNq0KR599NE48sgj4/TTT4/m5uaYOXNmjB49Om666aZobm6OhQsXRkVFRSxfvjyvWgQLAAAAMMg89thjceKJJ3Zor6mpibq6utixY0d89atfjTvuuCNee+212GeffeJDH/pQXHPNNXHEEUdERMTrr78eX/jCF2L58uWx1157xWmnnRY33HBDjB07Nq9aBAsAAABAMttNAgAAAMkECwAAAEAywQIAAACQTLAAAAAAJBMsAAAAAMkECwAAAEAywQIAAACQTLAAAAAAJBMsAAAAAMkECwAAAEAywQIAAACQTLAAAAAAJPv/qBfBJERGOJ4AAAAASUVORK5CYII=", + "image/png": "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/Mc2284555zs05/+dEHrpHdERHb33Xd3uc//+l//K/vQhz7UZtu8efOyU045pYCV0Zu6c59bO+GEE7JLL720YPXwB3osFMn27dtj9erVcdJJJ7VsKykpiZNOOimefPLJTo+75pprYty4cXHRRRcVo0x6IPUeb926NSZNmhTV1dVx5plnxq9//etilEuClHv84x//OI477rhYuHBh7LvvvnH44YfHN7/5zWhsbCxW2eQp9b3c2tKlS+O8886Lvfbaq1Bl0gMp9/j444+P1atXt3Slf/nll+OBBx6IT3ziE0Wpmfyk3OOGhoZ2wxH32GOPePzxxwtaK8Xz5JNPtnlNRESccsop3f7dDnROsFAk//3f/x2NjY2x7777ttm+7777xsaNGzs85vHHH4+lS5fGbbfdVowS6aGUe3zIIYfEP/3TP8W9994b//Iv/xJNTU1x/PHHR11dXTFKJk8p9/jll1+OH/7wh9HY2BgPPPBA/O3f/m1cf/318fWvf70YJZMg5T63tnLlynjuuefi4osvLlSJ9FDKPf7Upz4V11xzTcyaNSuGDRsWkydPjjlz5hgK0U+l3ONTTjklFi9eHGvWrImmpqZ4+OGHW4Y5MThs3Lixw9dEfX19/L//9//6qCoYHAQL/dS7774bF1xwQdx2222xzz779HU5FMhxxx0Xn/nMZ+Koo46KE044Ie66664YO3Zs3HLLLX1dGr2kqakpxo0bF7feemscc8wxMW/evPjqV78a/+f//J++Lo0CWbp0aRxxxBExY8aMvi6FXvToo4/GN7/5zfje974XTz/9dNx1113xb//2b/H3f//3fV0aveQ73/lOTJ06NQ499NAYPnx4XHLJJfHZz342Skr8uQywO2V9XcBQsc8++0RpaWn87ne/a7P9d7/7XYwfP77d/uvWrYv169fH6aef3rKtqakpIiLKysrixRdfjMmTJxe2aPKS7z3uyLBhw+Loo4+OtWvXFqJEeijlHk+YMCGGDRsWpaWlLdsOO+yw2LhxY2zfvj2GDx9e0JrJX0/ey9u2bYtly5bFNddcU8gS6aGUe/y3f/u3ccEFF7T0RDniiCNi27Zt8fnPfz6++tWvanz2Myn3eOzYsXHPPffE73//+3jrrbdi4sSJccUVV8RBBx1UjJIpgvHjx3f4mqioqIg99tijj6qCwcG/gkUyfPjwOOaYY+KRRx5p2dbU1BSPPPJIHHfcce32P/TQQ+PZZ5+NX/7yly2PM844o2UW2+rq6mKWTzfke4870tjYGM8++2xMmDChUGXSAyn3eObMmbF27dqWYDAi4qWXXooJEyYIFfqpnryX77zzzmhoaIjzzz+/0GXSAyn3+L333msXHjQHhlmWFa5YkvTkfTxixIjYb7/9YufOnfGjH/0ozjzzzEKXS5Ecd9xxbV4TEREPP/xwt/9OA7rQ17NHDiXLli3LysvLs9ra2uw3v/lN9vnPfz77wAc+kG3cuDHLsiy74IILsiuuuKLT460K0f/le4+vvvrq7KGHHsrWrVuXrV69OjvvvPOyESNGZL/+9a/76ltgN/K9x6+++mo2atSo7JJLLslefPHF7P7778/GjRuXff3rX++rb4FuSP19PWvWrGzevHnFLpcE+d7jq666Khs1alT2gx/8IHv55Zez5cuXZ5MnT84++clP9tW3wG7ke49/8YtfZD/60Y+ydevWZY899lh24oknZgceeGD29ttv99F3wO68++672TPPPJM988wzWURkixcvzp555pnslVdeybIsy6644orsggsuaNn/5Zdfzvbcc8/sr/7qr7Lnn38+u+mmm7LS0tLswQcf7KtvgW7I9z5nWday/zHHHJN96lOfyp555hl/XxeYYKHIvvvd72b7779/Nnz48GzGjBnZL37xi5bnTjjhhGz+/PmdHitYGBjyuceLFi1q2XfffffNPvGJT2RPP/10H1RNPvJ9H//85z/Pjj322Ky8vDw76KCDsm984xvZzp07i1w1+cr3Pr/wwgtZRGTLly8vcqWkyuce79ixI/va176WTZ48ORsxYkRWXV2d/cVf/IVGZz+Xzz1+9NFHs8MOOywrLy/PxowZk11wwQXZa6+91gdV010rVqzIIqLdo/m+zp8/PzvhhBPaHXPUUUdlw4cPzw466KCspqam6HWTn5T73NH+kyZNKnrtQ0kuy/TfAwAAANKYYwEAAABIJlgAAAAAkgkWAAAAgGSCBQAAACCZYAEAAABIJlgAAAAAkgkWAAAAgGSCBQAAABhgHnvssTj99NNj4sSJkcvl4p577sn7HFmWxXXXXRcHH3xwlJeXx3777Rff+MY38j5PWd5HAAAAAH1q27ZtMW3atLjwwgvjnHPOSTrHpZdeGsuXL4/rrrsujjjiiNi8eXNs3rw57/PksizLkioAAAAA+lwul4u77747zjrrrJZtDQ0N8dWvfjV+8IMfxDvvvBOHH354fPvb3445c+ZERMTzzz8fRx55ZDz33HNxyCGH9Oj6hkIAAADAIHPJJZfEk08+GcuWLYv/+q//inPPPTc+/vGPx5o1ayIi4r777ouDDjoo7r///jjwwAPjgAMOiIsvvjipx4JgAQAAAAaRV199NWpqauLOO++M2bNnx+TJk+Pyyy+PWbNmRU1NTUREvPzyy/HKK6/EnXfeGbfffnvU1tbG6tWr40//9E/zvp45FgAAAGAQefbZZ6OxsTEOPvjgNtsbGhpizJgxERHR1NQUDQ0Ncfvtt7fst3Tp0jjmmGPixRdfzGt4hGABAAAABpGtW7dGaWlprF69OkpLS9s8N3LkyIiImDBhQpSVlbUJHw477LCIeL/Hg2ABAAAAhqijjz46Ghsb480334zZs2d3uM/MmTNj586dsW7dupg8eXJERLz00ksRETFp0qS8rmdVCAAAABhgtm7dGmvXro2I94OExYsXx9y5c2P06NGx//77x/nnnx9PPPFEXH/99XH00UfHpk2b4pFHHokjjzwyTjvttGhqaorp06fHyJEj48Ybb4ympqZYuHBhVFRUxPLly/OqRbAAAAAAA8yjjz4ac+fObbd9/vz5UVtbGzt27Iivf/3rcfvtt8drr70W++yzT3zkIx+Jq6++Oo444oiIiHj99dfjS1/6Uixfvjz22muvOPXUU+P666+P0aNH51WLYAEAAABIZrlJAAAAIJlgAQAAAEgmWAAAAACSCRYAAACAZIIFAAAAIJlgAQAAAEgmWAAAAACSCRYAAACAZIIFAAAAIJlgAQAAAEgmWAAAAACSCRYAAACAZP8f5zjBJNsYZ3cAAAAASUVORK5CYII=", "text/plain": [ "
" ] @@ -1433,21 +1433,20 @@ "name": "stderr", "output_type": "stream", "text": [ - "DEBUG:ddlpy.ddlpy:requesting: {'AquoMetadataLijst': [{'Eenheid': {'Code': 'cm'}, 'Grootheid': {'Code': 'WATHTBRKD'}, 'Hoedanigheid': {'Code': 'NAP'}, 'Groepering': {'Code': 'GETETBRKD2'}}], 'LocatieLijst': [{'X': 586550.994420996, 'Y': 5772806.43069697, 'Code': 'SCHEVNGN'}], 'Periode': {'Begindatumtijd': '2019-01-01T00:00:00.000+00:00', 'Einddatumtijd': '2020-02-01T00:00:00.000+00:00'}}\n", - " 0%| | 0/13 [00:00WaarnemingMetadata.ReferentievlakLijst\n", " WaarnemingMetadata.OpdrachtgevendeInstantieLijst\n", " WaarnemingMetadata.KwaliteitswaardecodeLijst\n", - " Tijdstip\n", " AquoMetadata_MessageID\n", " Parameter_Wat_Omschrijving\n", " BemonsteringsApparaat.Code\n", " BemonsteringsApparaat.Omschrijving\n", + " BemonsteringsMethode.Code\n", " ...\n", " WaardeBepalingsmethode.Omschrijving\n", " WaardeBewerkingsmethode.Code\n", @@ -1568,11 +1567,11 @@ " NVT\n", " RIKZMON_WAT\n", " 00\n", - " 2019-01-01T07:15:00.000+01:00\n", " 10846\n", " Waterhoogte berekend Oppervlaktewater t.o.v. N...\n", " NVT\n", " Waarde is niet van toepassing\n", + " NVT\n", " ...\n", " Astronomische waterhoogte mbv harmonische analyse\n", " NVT\n", @@ -1592,11 +1591,11 @@ " NVT\n", " RIKZMON_WAT\n", " 00\n", - " 2019-01-01T11:25:00.000+01:00\n", " 10846\n", " Waterhoogte berekend Oppervlaktewater t.o.v. N...\n", " NVT\n", " Waarde is niet van toepassing\n", + " NVT\n", " ...\n", " Astronomische waterhoogte mbv harmonische analyse\n", " NVT\n", @@ -1616,11 +1615,11 @@ " NVT\n", " RIKZMON_WAT\n", " 00\n", - " 2019-01-01T19:20:00.000+01:00\n", " 10846\n", " Waterhoogte berekend Oppervlaktewater t.o.v. N...\n", " NVT\n", " Waarde is niet van toepassing\n", + " NVT\n", " ...\n", " Astronomische waterhoogte mbv harmonische analyse\n", " NVT\n", @@ -1640,11 +1639,11 @@ " NVT\n", " RIKZMON_WAT\n", " 00\n", - " 2019-01-01T23:56:00.000+01:00\n", " 10846\n", " Waterhoogte berekend Oppervlaktewater t.o.v. N...\n", " NVT\n", " Waarde is niet van toepassing\n", + " NVT\n", " ...\n", " Astronomische waterhoogte mbv harmonische analyse\n", " NVT\n", @@ -1664,11 +1663,11 @@ " NVT\n", " RIKZMON_WAT\n", " 00\n", - " 2019-01-02T08:18:00.000+01:00\n", " 10846\n", " Waterhoogte berekend Oppervlaktewater t.o.v. N...\n", " NVT\n", " Waarde is niet van toepassing\n", + " NVT\n", " ...\n", " Astronomische waterhoogte mbv harmonische analyse\n", " NVT\n", @@ -1712,11 +1711,11 @@ " NVT\n", " RIKZMON_WAT\n", " 00\n", - " 2020-01-30T18:44:00.000+01:00\n", " 10846\n", " Waterhoogte berekend Oppervlaktewater t.o.v. N...\n", " NVT\n", " Waarde is niet van toepassing\n", + " NVT\n", " ...\n", " Astronomische waterhoogte mbv harmonische analyse\n", " NVT\n", @@ -1736,11 +1735,11 @@ " NVT\n", " RIKZMON_WAT\n", " 00\n", - " 2020-01-31T02:24:00.000+01:00\n", " 10846\n", " Waterhoogte berekend Oppervlaktewater t.o.v. N...\n", " NVT\n", " Waarde is niet van toepassing\n", + " NVT\n", " ...\n", " Astronomische waterhoogte mbv harmonische analyse\n", " NVT\n", @@ -1760,11 +1759,11 @@ " NVT\n", " RIKZMON_WAT\n", " 00\n", - " 2020-01-31T07:02:00.000+01:00\n", " 10846\n", " Waterhoogte berekend Oppervlaktewater t.o.v. N...\n", " NVT\n", " Waarde is niet van toepassing\n", + " NVT\n", " ...\n", " Astronomische waterhoogte mbv harmonische analyse\n", " NVT\n", @@ -1784,11 +1783,11 @@ " NVT\n", " RIKZMON_WAT\n", " 00\n", - " 2020-01-31T14:52:00.000+01:00\n", " 10846\n", " Waterhoogte berekend Oppervlaktewater t.o.v. N...\n", " NVT\n", " Waarde is niet van toepassing\n", + " NVT\n", " ...\n", " Astronomische waterhoogte mbv harmonische analyse\n", " NVT\n", @@ -1808,11 +1807,11 @@ " NVT\n", " RIKZMON_WAT\n", " 00\n", - " 2020-01-31T19:20:00.000+01:00\n", " 10846\n", " Waterhoogte berekend Oppervlaktewater t.o.v. N...\n", " NVT\n", " Waarde is niet van toepassing\n", + " NVT\n", " ...\n", " Astronomische waterhoogte mbv harmonische analyse\n", " NVT\n", @@ -1827,7 +1826,7 @@ " \n", " \n", "\n", - "

1530 rows × 54 columns

\n", + "

1530 rows × 53 columns

\n", "" ], "text/plain": [ @@ -1901,20 +1900,6 @@ "2020-01-31 14:52:00+01:00 00 \n", "2020-01-31 19:20:00+01:00 00 \n", "\n", - " Tijdstip \\\n", - "time \n", - "2019-01-01 07:15:00+01:00 2019-01-01T07:15:00.000+01:00 \n", - "2019-01-01 11:25:00+01:00 2019-01-01T11:25:00.000+01:00 \n", - "2019-01-01 19:20:00+01:00 2019-01-01T19:20:00.000+01:00 \n", - "2019-01-01 23:56:00+01:00 2019-01-01T23:56:00.000+01:00 \n", - "2019-01-02 08:18:00+01:00 2019-01-02T08:18:00.000+01:00 \n", - "... ... \n", - "2020-01-30 18:44:00+01:00 2020-01-30T18:44:00.000+01:00 \n", - "2020-01-31 02:24:00+01:00 2020-01-31T02:24:00.000+01:00 \n", - "2020-01-31 07:02:00+01:00 2020-01-31T07:02:00.000+01:00 \n", - "2020-01-31 14:52:00+01:00 2020-01-31T14:52:00.000+01:00 \n", - "2020-01-31 19:20:00+01:00 2020-01-31T19:20:00.000+01:00 \n", - "\n", " AquoMetadata_MessageID \\\n", "time \n", "2019-01-01 07:15:00+01:00 10846 \n", @@ -1957,19 +1942,33 @@ "2020-01-31 14:52:00+01:00 NVT \n", "2020-01-31 19:20:00+01:00 NVT \n", "\n", - " BemonsteringsApparaat.Omschrijving ... \\\n", - "time ... \n", - "2019-01-01 07:15:00+01:00 Waarde is niet van toepassing ... \n", - "2019-01-01 11:25:00+01:00 Waarde is niet van toepassing ... \n", - "2019-01-01 19:20:00+01:00 Waarde is niet van toepassing ... \n", - "2019-01-01 23:56:00+01:00 Waarde is niet van toepassing ... \n", - "2019-01-02 08:18:00+01:00 Waarde is niet van toepassing ... \n", - "... ... ... \n", - "2020-01-30 18:44:00+01:00 Waarde is niet van toepassing ... \n", - "2020-01-31 02:24:00+01:00 Waarde is niet van toepassing ... \n", - "2020-01-31 07:02:00+01:00 Waarde is niet van toepassing ... \n", - "2020-01-31 14:52:00+01:00 Waarde is niet van toepassing ... \n", - "2020-01-31 19:20:00+01:00 Waarde is niet van toepassing ... \n", + " BemonsteringsApparaat.Omschrijving \\\n", + "time \n", + "2019-01-01 07:15:00+01:00 Waarde is niet van toepassing \n", + "2019-01-01 11:25:00+01:00 Waarde is niet van toepassing \n", + "2019-01-01 19:20:00+01:00 Waarde is niet van toepassing \n", + "2019-01-01 23:56:00+01:00 Waarde is niet van toepassing \n", + "2019-01-02 08:18:00+01:00 Waarde is niet van toepassing \n", + "... ... \n", + "2020-01-30 18:44:00+01:00 Waarde is niet van toepassing \n", + "2020-01-31 02:24:00+01:00 Waarde is niet van toepassing \n", + "2020-01-31 07:02:00+01:00 Waarde is niet van toepassing \n", + "2020-01-31 14:52:00+01:00 Waarde is niet van toepassing \n", + "2020-01-31 19:20:00+01:00 Waarde is niet van toepassing \n", + "\n", + " BemonsteringsMethode.Code ... \\\n", + "time ... \n", + "2019-01-01 07:15:00+01:00 NVT ... \n", + "2019-01-01 11:25:00+01:00 NVT ... \n", + "2019-01-01 19:20:00+01:00 NVT ... \n", + "2019-01-01 23:56:00+01:00 NVT ... \n", + "2019-01-02 08:18:00+01:00 NVT ... \n", + "... ... ... \n", + "2020-01-30 18:44:00+01:00 NVT ... \n", + "2020-01-31 02:24:00+01:00 NVT ... \n", + "2020-01-31 07:02:00+01:00 NVT ... \n", + "2020-01-31 14:52:00+01:00 NVT ... \n", + "2020-01-31 19:20:00+01:00 NVT ... \n", "\n", " WaardeBepalingsmethode.Omschrijving \\\n", "time \n", @@ -2069,7 +2068,7 @@ "2020-01-31 14:52:00+01:00 5.772806e+06 \n", "2020-01-31 19:20:00+01:00 5.772806e+06 \n", "\n", - "[1530 rows x 54 columns]" + "[1530 rows x 53 columns]" ] }, "execution_count": 12, @@ -2081,6 +2080,472 @@ "measurements" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Convert to xarray" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.Dataset> Size: 73kB\n",
+       "Dimensions:                                       (time: 1530)\n",
+       "Coordinates:\n",
+       "  * time                                          (time) datetime64[ns] 12kB ...\n",
+       "Data variables:\n",
+       "    WaarnemingMetadata.StatuswaardeLijst          (time) object 12kB 'Ongecon...\n",
+       "    WaarnemingMetadata.KwaliteitswaardecodeLijst  (time) object 12kB '00' ......\n",
+       "    Groepering.Code                               (time) object 12kB 'GETETBR...\n",
+       "    WaardeBepalingsmethode.Code                   (time) object 12kB 'other:F...\n",
+       "    Meetwaarde.Waarde_Numeriek                    (time) float64 12kB -53.0 ....\n",
+       "Attributes: (12/27)\n",
+       "    BemonsteringsApparaat.Code:                        NVT\n",
+       "    BemonsteringsMethode.Code:                         NVT\n",
+       "    BemonsteringsSoort.Code:                           NVT\n",
+       "    BioTaxon.Code:                                     NVT\n",
+       "    BioTaxon_Compartiment.Code:                        NVT\n",
+       "    MeetApparaat.Code:                                 NVT\n",
+       "    ...                                                ...\n",
+       "    Hoedanigheid.Code:                                 NAP\n",
+       "    Code:                                              SCHEVNGN\n",
+       "    Naam:                                              Scheveningen\n",
+       "    Coordinatenstelsel:                                25831\n",
+       "    X:                                                 586550.994420996\n",
+       "    Y:                                                 5772806.43069697
" + ], + "text/plain": [ + " Size: 73kB\n", + "Dimensions: (time: 1530)\n", + "Coordinates:\n", + " * time (time) datetime64[ns] 12kB ...\n", + "Data variables:\n", + " WaarnemingMetadata.StatuswaardeLijst (time) object 12kB 'Ongecon...\n", + " WaarnemingMetadata.KwaliteitswaardecodeLijst (time) object 12kB '00' ......\n", + " Groepering.Code (time) object 12kB 'GETETBR...\n", + " WaardeBepalingsmethode.Code (time) object 12kB 'other:F...\n", + " Meetwaarde.Waarde_Numeriek (time) float64 12kB -53.0 ....\n", + "Attributes: (12/27)\n", + " BemonsteringsApparaat.Code: NVT\n", + " BemonsteringsMethode.Code: NVT\n", + " BemonsteringsSoort.Code: NVT\n", + " BioTaxon.Code: NVT\n", + " BioTaxon_Compartiment.Code: NVT\n", + " MeetApparaat.Code: NVT\n", + " ... ...\n", + " Hoedanigheid.Code: NAP\n", + " Code: SCHEVNGN\n", + " Naam: Scheveningen\n", + " Coordinatenstelsel: 25831\n", + " X: 586550.994420996\n", + " Y: 5772806.43069697" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "drop_if_constant = [\"WaarnemingMetadata.OpdrachtgevendeInstantieLijst\",\n", + " \"WaarnemingMetadata.BemonsteringshoogteLijst\",\n", + " \"WaarnemingMetadata.ReferentievlakLijst\",\n", + " \"AquoMetadata_MessageID\", \n", + " \"BioTaxonType\",\n", + " \"BemonsteringsSoort.Code\", \n", + " \"Compartiment.Code\", \"Eenheid.Code\", \"Grootheid.Code\", \"Hoedanigheid.Code\",\n", + " ]\n", + "ds = ddlpy.dataframe_to_xarray(measurements, drop_if_constant=drop_if_constant)\n", + "ds" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/tests/test_ddlpy.py b/tests/test_ddlpy.py index 2b7f369..2975559 100755 --- a/tests/test_ddlpy.py +++ b/tests/test_ddlpy.py @@ -155,14 +155,6 @@ def test_measurements_duplicated(measurements): assert isinstance(meas_clean.index, pd.DatetimeIndex) -def test_simplify_dataframe(measurements): - assert len(measurements.columns) == 53 - meas_simple = ddlpy.simplify_dataframe(measurements) - assert hasattr(meas_simple, "attrs") - assert len(meas_simple.attrs) == 50 - assert len(meas_simple.columns) == 3 - - datetype_list = ["string", "pd.Timestamp", "dt.datetime", "mixed"] @pytest.mark.parametrize("datetype", datetype_list) def test_check_convert_dates(datetype): @@ -193,3 +185,43 @@ def test_check_convert_wrongorder(): with pytest.raises(ValueError): start_date_out, end_date_out = ddlpy.ddlpy._check_convert_dates(end_date, start_date) + +def test_simplify_dataframe(measurements): + assert len(measurements.columns) == 53 + meas_simple = ddlpy.simplify_dataframe(measurements) + assert hasattr(meas_simple, "attrs") + assert len(meas_simple.attrs) == 50 + assert len(meas_simple.columns) == 3 + + +def test_dataframe_to_xarray(measurements): + drop_if_constant = ["WaarnemingMetadata.OpdrachtgevendeInstantieLijst", + "WaarnemingMetadata.BemonsteringshoogteLijst", + "WaarnemingMetadata.ReferentievlakLijst", + "AquoMetadata_MessageID", + "BemonsteringsSoort.Code", + "Compartiment.Code", "Eenheid.Code", "Grootheid.Code", "Hoedanigheid.Code", + ] + ds_clean = ddlpy.dataframe_to_xarray(measurements, drop_if_constant) + + # check if constant value that was not in drop_if_constant list is indeed not dropped + assert "MeetApparaat.Code" in ds_clean.data_vars + assert len(ds_clean["MeetApparaat.Code"]) > 0 + + for varname in drop_if_constant: + if varname == "WaarnemingMetadata.OpdrachtgevendeInstantieLijst": + continue + assert varname not in ds_clean.data_vars + assert varname in ds_clean.attrs.keys() + assert "WaarnemingMetadata.OpdrachtgevendeInstantieLijst" in ds_clean.data_vars + assert "WaarnemingMetadata.OpdrachtgevendeInstantieLijst" not in ds_clean.attrs.keys() + + data_vars_list = ['WaarnemingMetadata.StatuswaardeLijst', + 'WaarnemingMetadata.KwaliteitswaardecodeLijst', + 'MeetApparaat.Code', + 'WaardeBepalingsmethode.Code', + 'Meetwaarde.Waarde_Numeriek'] + for varname in data_vars_list: + assert varname in ds_clean.data_vars + + assert "X" in ds_clean.attrs.keys()