Skip to content

Instantly share code, notes, and snippets.

@joAschauer
Last active July 8, 2021 08:27
Show Gist options
  • Save joAschauer/40c9e11eb0484ec54009201603ede466 to your computer and use it in GitHub Desktop.
Save joAschauer/40c9e11eb0484ec54009201603ede466 to your computer and use it in GitHub Desktop.
use nixmass R package from python
# this file can be sourced from python with rpy2
library(nixmass)
calculate_deltasnow <- function(df_in){
#' Calculate nixmass delta snow and return dataframe instead of nixmass object
#'
#' @param df_in The dataframe containing the data
#
if(df_in$hs[1]!=0) {
# if first HS datapoint is not zero, raise second datapoint by the half of first and set first to zero.
df_in$hs[2]<-df_in$hs[2]+(df_in$hs[1]/2)
df_in$hs[1]<-0}
# call nixmass function with delta.snow option
SWEnixmass<-nixmass(df_in, model="delta.snow", verbose=F)
# create a data.frame containing only SWE from the nixmass object.
SWE_delta_snow<-SWEnixmass$swe$delta.snow
date <- SWEnixmass$date
df_out <- data.frame(date, SWE_delta_snow)
return(df_out)
}
# -*- coding: utf-8 -*-
"""
Call nixmass R package from python with rpy2.
Sample HS data has been downloaded from the nixmass cran mirror:
https://github.com/cran/nixmass/blob/master/data/hsdata.RData
Feel free copy if something is helpful for your usecase.
Works for me with the following versions:
python: '3.7.6'
R: '3.6.1'
rpy2: '3.4.5'
pandas: '1.1.3'
@author: Johannes Aschauer
"""
import pandas as pd
import rpy2.robjects as ro
import rpy2.robjects.packages as rpackages
from rpy2.robjects.vectors import StrVector
from rpy2.robjects import pandas2ri
# R package setup and installaton:
REQUIRED_R_PACKAGES = ['nixmass']
utils = rpackages.importr('utils')
utils.chooseCRANmirror(ind=1)
PACKAGES_TO_INSTALL = [p for p in REQUIRED_R_PACKAGES if not rpackages.isinstalled(p)]
if len(PACKAGES_TO_INSTALL) > 0:
utils.install_packages(StrVector(PACKAGES_TO_INSTALL))
# activate automatic pandas to R conversion
pandas2ri.activate()
# Source the modified deltasnow function from R
ro.r['source']('calculate_deltasnow.R')
# create a pointer to a python function
calculate_deltasnow = ro.globalenv['calculate_deltasnow']
def append_delta_snow_SWE_column(df, hs_unit='m', swe_unit='mm'):
"""
Calculate SWE from HS with nixmass R package and append it to input.
Parameters
----------
df : pd.DataFrame
input data needs to have a column 'HS' or 'hs' and pd.DatetimeIndex.
hs_unit : str of {'mm', 'cm', 'm'}
Input HS unit. Will be transformed to [m] for the nixmass call. The
default is 'm'
swe_unit : str of {'mm', 'cm', 'm'}
Output unit of the appended SWE column
Returns
-------
df_modified : pd.DataFrame
includes column 'SWE_delta_snow' in the defined output `swe_unit`
"""
df = df.copy()
assert hs_unit in {'mm', 'cm', 'm'}
assert swe_unit in {'mm', 'cm', 'm'}
assert 'hs' in [c.lower() for c in df.columns]
assert isinstance(df.index, pd.DatetimeIndex)
unit_factor = {'mm': 0.001,
'cm': 0.01,
'm': 1.0}
# create water year column for grouping
df['wy'] = df.index.year.where(df.index.month<9, df.index.year+1)
to_concatenate = []
for wy, data in df.groupby('wy'):
# nixmass needs columns 'date' and 'hs'
df_R_in = (data
.reset_index(drop=False)
.rename(columns={'index': 'date',
data.index.name: 'date',
'HS': 'hs'},
errors='ignore')
.loc[:,['date', 'hs']])
# input HS for nixmass needs to be in [m]
df_R_in['hs'] = df_R_in['hs']*unit_factor[hs_unit]
# nixmass needs date as strings
df_R_in['date'] = df_R_in.date.astype(str)
# call R function
df_R_out = calculate_deltasnow(df_R_in)
# reconvert datetime format
df_R_out['date'] = pd.to_datetime(df_R_out['date'])
df_R_out = df_R_out.set_index('date')
# append modeled SWE to data
data['SWE_delta_snow'] = df_R_out['SWE_delta_snow']
# nixmass returns SWE in [mm]
data['SWE_delta_snow'] = data['SWE_delta_snow']*0.001/unit_factor[swe_unit]
to_concatenate.append(data)
df_modified = (pd.concat(to_concatenate, axis=0)
.drop(columns=['wy'])
)
return df_modified
if __name__ == '__main__':
# Test demo:
# load sample data for testing (HS given in [m])
data = pd.read_csv("sample_hsdata.csv",
index_col='date',
parse_dates=['date'])
data['hs'] = data['hs']*100 # many times HS comes in cm.
data_out = append_delta_snow_SWE_column(data, hs_unit='cm', swe_unit='mm')
data_out.plot()
# the `append_delta_snow_SWE_column` function can also very conveniently be used in .pipe()
# calls e.g. before monthly mean resampling:
data2 = (pd.read_csv("sample_hsdata.csv",
index_col='date',
parse_dates=['date'])
.pipe(append_delta_snow_SWE_column, hs_unit='m', swe_unit='m')
.resample('M').mean()
)
data2.plot()
date hs
1900-08-01 0
1900-08-02 0
1900-08-03 0
1900-08-04 0
1900-08-05 0
1900-08-06 0
1900-08-07 0
1900-08-08 0
1900-08-09 0
1900-08-10 0
1900-08-11 0
1900-08-12 0
1900-08-13 0
1900-08-14 0
1900-08-15 0
1900-08-16 0
1900-08-17 0
1900-08-18 0
1900-08-19 0
1900-08-20 0
1900-08-21 0
1900-08-22 0
1900-08-23 0
1900-08-24 0
1900-08-25 0
1900-08-26 0
1900-08-27 0
1900-08-28 0
1900-08-29 0
1900-08-30 0
1900-08-31 0
1900-09-01 0
1900-09-02 0
1900-09-03 0
1900-09-04 0
1900-09-05 0
1900-09-06 0
1900-09-07 0
1900-09-08 0
1900-09-09 0
1900-09-10 0
1900-09-11 0
1900-09-12 0
1900-09-13 0
1900-09-14 0
1900-09-15 0
1900-09-16 0
1900-09-17 0
1900-09-18 0
1900-09-19 0
1900-09-20 0
1900-09-21 0
1900-09-22 0
1900-09-23 0
1900-09-24 0
1900-09-25 0
1900-09-26 0
1900-09-27 0
1900-09-28 0
1900-09-29 0
1900-09-30 0
1900-10-01 0
1900-10-02 0
1900-10-03 0
1900-10-04 0
1900-10-05 0
1900-10-06 0
1900-10-07 0
1900-10-08 0
1900-10-09 0
1900-10-10 0
1900-10-11 0
1900-10-12 0
1900-10-13 0
1900-10-14 0
1900-10-15 0
1900-10-16 0
1900-10-17 0
1900-10-18 0
1900-10-19 0
1900-10-20 0
1900-10-21 0
1900-10-22 0
1900-10-23 0
1900-10-24 0
1900-10-25 0
1900-10-26 0
1900-10-27 0
1900-10-28 0
1900-10-29 0
1900-10-30 0
1900-10-31 0
1900-11-01 0
1900-11-02 0
1900-11-03 0
1900-11-04 0
1900-11-05 0
1900-11-06 0
1900-11-07 0
1900-11-08 0
1900-11-09 0
1900-11-10 0
1900-11-11 0
1900-11-12 0
1900-11-13 0
1900-11-14 0
1900-11-15 0
1900-11-16 0
1900-11-17 0
1900-11-18 0
1900-11-19 0
1900-11-20 0
1900-11-21 0
1900-11-22 0.05
1900-11-23 0.1
1900-11-24 0.09
1900-11-25 0.11
1900-11-26 0.1
1900-11-27 0.09
1900-11-28 0.07
1900-11-29 0.06
1900-11-30 0.02
1900-12-01 0
1900-12-02 0
1900-12-03 0.05
1900-12-04 0.04
1900-12-05 0.03
1900-12-06 0.02
1900-12-07 0.05
1900-12-08 0.07
1900-12-09 0.07
1900-12-10 0.06
1900-12-11 0.06
1900-12-12 0.06
1900-12-13 0.05
1900-12-14 0.05
1900-12-15 0.05
1900-12-16 0.05
1900-12-17 0.05
1900-12-18 0.11
1900-12-19 0.18
1900-12-20 0.19
1900-12-21 0.3
1900-12-22 0.2
1900-12-23 0.15
1900-12-24 0.12
1900-12-25 0.1
1900-12-26 0.1
1900-12-27 0.1
1900-12-28 0.1
1900-12-29 0.1
1900-12-30 0.1
1900-12-31 0.1
1901-01-01 0.1
1901-01-02 0.11
1901-01-03 0.12
1901-01-04 0.12
1901-01-05 0.12
1901-01-06 0.12
1901-01-07 0.12
1901-01-08 0.12
1901-01-09 0.12
1901-01-10 0.12
1901-01-11 0.12
1901-01-12 0.12
1901-01-13 0.12
1901-01-14 0.12
1901-01-15 0.13
1901-01-16 0.13
1901-01-17 0.13
1901-01-18 0.12
1901-01-19 0.12
1901-01-20 0.12
1901-01-21 0.16
1901-01-22 0.17
1901-01-23 0.17
1901-01-24 0.15
1901-01-25 0.15
1901-01-26 0.15
1901-01-27 0.15
1901-01-28 0.24
1901-01-29 0.27
1901-01-30 0.25
1901-01-31 0.25
1901-02-01 0.23
1901-02-02 0.23
1901-02-03 0.21
1901-02-04 0.21
1901-02-05 0.2
1901-02-06 0.16
1901-02-07 0.15
1901-02-08 0.16
1901-02-09 0.19
1901-02-10 0.23
1901-02-11 0.26
1901-02-12 0.36
1901-02-13 0.64
1901-02-14 0.86
1901-02-15 0.81
1901-02-16 0.64
1901-02-17 0.79
1901-02-18 0.95
1901-02-19 0.89
1901-02-20 0.86
1901-02-21 1.1
1901-02-22 1.2
1901-02-23 1.07
1901-02-24 1.3
1901-02-25 1.1
1901-02-26 1.05
1901-02-27 1.22
1901-02-28 1.07
1901-03-01 0.97
1901-03-02 0.88
1901-03-03 0.83
1901-03-04 0.77
1901-03-05 0.72
1901-03-06 0.69
1901-03-07 0.76
1901-03-08 0.74
1901-03-09 0.74
1901-03-10 0.77
1901-03-11 0.72
1901-03-12 0.87
1901-03-13 0.89
1901-03-14 0.83
1901-03-15 0.77
1901-03-16 0.76
1901-03-17 0.69
1901-03-18 0.65
1901-03-19 0.62
1901-03-20 0.67
1901-03-21 0.64
1901-03-22 0.62
1901-03-23 0.64
1901-03-24 0.66
1901-03-25 0.74
1901-03-26 0.84
1901-03-27 0.79
1901-03-28 0.68
1901-03-29 0.67
1901-03-30 0.74
1901-03-31 0.62
1901-04-01 0.53
1901-04-02 0.46
1901-04-03 0.4
1901-04-04 0.35
1901-04-05 0.25
1901-04-06 0.2
1901-04-07 0.15
1901-04-08 0.08
1901-04-09 0.05
1901-04-10 0
1901-04-11 0
1901-04-12 0
1901-04-13 0
1901-04-14 0
1901-04-15 0
1901-04-16 0
1901-04-17 0
1901-04-18 0
1901-04-19 0
1901-04-20 0
1901-04-21 0
1901-04-22 0
1901-04-23 0
1901-04-24 0
1901-04-25 0
1901-04-26 0
1901-04-27 0
1901-04-28 0
1901-04-29 0
1901-04-30 0
1901-05-01 0
1901-05-02 0
1901-05-03 0
1901-05-04 0
1901-05-05 0
1901-05-06 0
1901-05-07 0
1901-05-08 0
1901-05-09 0
1901-05-10 0
1901-05-11 0
1901-05-12 0
1901-05-13 0
1901-05-14 0
1901-05-15 0
1901-05-16 0
1901-05-17 0
1901-05-18 0
1901-05-19 0
1901-05-20 0
1901-05-21 0
1901-05-22 0
1901-05-23 0
1901-05-24 0
1901-05-25 0
1901-05-26 0
1901-05-27 0
1901-05-28 0
1901-05-29 0
1901-05-30 0
1901-05-31 0
1901-06-01 0
1901-06-02 0
1901-06-03 0
1901-06-04 0
1901-06-05 0
1901-06-06 0
1901-06-07 0
1901-06-08 0
1901-06-09 0
1901-06-10 0
1901-06-11 0
1901-06-12 0
1901-06-13 0
1901-06-14 0
1901-06-15 0
1901-06-16 0
1901-06-17 0
1901-06-18 0
1901-06-19 0
1901-06-20 0
1901-06-21 0
1901-06-22 0
1901-06-23 0
1901-06-24 0
1901-06-25 0
1901-06-26 0
1901-06-27 0
1901-06-28 0
1901-06-29 0
1901-06-30 0
1901-07-01 0
1901-07-02 0
1901-07-03 0
1901-07-04 0
1901-07-05 0
1901-07-06 0
1901-07-07 0
1901-07-08 0
1901-07-09 0
1901-07-10 0
1901-07-11 0
1901-07-12 0
1901-07-13 0
1901-07-14 0
1901-07-15 0
1901-07-16 0
1901-07-17 0
1901-07-18 0
1901-07-19 0
1901-07-20 0
1901-07-21 0
1901-07-22 0
1901-07-23 0
1901-07-24 0
1901-07-25 0
1901-07-26 0
1901-07-27 0
1901-07-28 0
1901-07-29 0
1901-07-30 0
1901-07-31 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment