From a680dbe25003b085adc7b7063329e647ca9d2c7d Mon Sep 17 00:00:00 2001 From: Anton Driesse Date: Fri, 12 Jul 2019 13:06:50 +0200 Subject: [PATCH 1/4] Put product renaming code in a separate function, simplify, add warning. --- pvlib/pvsystem.py | 47 ++++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 35701bd3a2..1bb7289c1b 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -1647,26 +1647,39 @@ def retrieve_sam(name=None, path=None): return _parse_raw_sam_df(csvdata) +def _normalize_sam_product_names(names): + ''' + Replace special characters within the product names to make them more + suitable fur use as Dataframe column names. + ''' + import warnings + + BAD_CHARS = ' -.()[]:+/",' + GOOD_CHARS = '____________' + + mapping = str.maketrans(BAD_CHARS, GOOD_CHARS) + names = pd.Series(data=names) + norm_names = names.str.translate(mapping) + + n_duplicates = names.duplicated().sum() + if n_duplicates > 0: + warnings.warn ('Original names contain %d duplicate(s).' % n_duplicates) + + n_duplicates = norm_names.duplicated().sum() + if n_duplicates > 0: + warnings.warn ('Normalized names contain %d duplicate(s).' % n_duplicates) + + return norm_names.values + + def _parse_raw_sam_df(csvdata): + df = pd.read_csv(csvdata, index_col=0, skiprows=[1, 2]) - colnames = df.columns.values.tolist() - parsedcolnames = [] - for cn in colnames: - parsedcolnames.append(cn.replace(' ', '_')) - - df.columns = parsedcolnames - - parsedindex = [] - for index in df.index: - parsedindex.append(index.replace(' ', '_').replace('-', '_') - .replace('.', '_').replace('(', '_') - .replace(')', '_').replace('[', '_') - .replace(']', '_').replace(':', '_') - .replace('+', '_').replace('/', '_') - .replace('"', '_').replace(',', '_')) - - df.index = parsedindex + + df.columns = df.columns.str.replace(' ', '_') + df.index = _normalize_sam_product_names(df.index) df = df.transpose() + if 'ADRCoefficients' in df.index: ad_ce = 'ADRCoefficients' # for each inverter, parses a string of coefficients like From c160a01a3fe510a183d1eb4797140ded34fdbfcb Mon Sep 17 00:00:00 2001 From: Anton Driesse Date: Fri, 19 Jul 2019 11:26:25 +0200 Subject: [PATCH 2/4] Add test and pacify stickler somewhat. --- pvlib/pvsystem.py | 4 ++-- pvlib/test/test_pvsystem.py | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 1bb7289c1b..115adde76a 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -1663,11 +1663,11 @@ def _normalize_sam_product_names(names): n_duplicates = names.duplicated().sum() if n_duplicates > 0: - warnings.warn ('Original names contain %d duplicate(s).' % n_duplicates) + warnings.warn('Original names contain %d duplicate(s).' % n_duplicates) n_duplicates = norm_names.duplicated().sum() if n_duplicates > 0: - warnings.warn ('Normalized names contain %d duplicate(s).' % n_duplicates) + warnings.warn('Normalized names contain %d duplicate(s).' % n_duplicates) return norm_names.values diff --git a/pvlib/test/test_pvsystem.py b/pvlib/test/test_pvsystem.py index 17f70e9d12..68d5a498e4 100644 --- a/pvlib/test/test_pvsystem.py +++ b/pvlib/test/test_pvsystem.py @@ -147,6 +147,28 @@ def test_PVSystem_physicaliam(mocker): pvsystem.physicaliam.assert_called_once_with(thetas, **module_parameters) assert iam < 1. +def test__normalize_sam_product_names(): + + BAD_NAMES = [' -.()[]:+/",', 'Module[1]'] + NORM_NAMES = ['____________', 'Module_1_'] + + norm_names = pvsystem._normalize_sam_product_names(BAD_NAMES) + assert list(norm_names) == NORM_NAMES + + BAD_NAMES = ['Module[1]', 'Module(1)'] + NORM_NAMES = ['Module_1_', 'Module_1_'] + + with pytest.warns(UserWarning): + norm_names = pvsystem._normalize_sam_product_names(BAD_NAMES) + assert list(norm_names) == NORM_NAMES + + BAD_NAMES = ['Module[1]', 'Module[1]'] + NORM_NAMES = ['Module_1_', 'Module_1_'] + + with pytest.warns(UserWarning): + norm_names = pvsystem._normalize_sam_product_names(BAD_NAMES) + assert list(norm_names) == NORM_NAMES + # if this completes successfully we'll be able to do more tests below. @pytest.fixture(scope="session") From fb236999337f740a17338c31cfda69b148f3a3ae Mon Sep 17 00:00:00 2001 From: Anton Driesse Date: Fri, 19 Jul 2019 11:30:57 +0200 Subject: [PATCH 3/4] Add one comment --- pvlib/pvsystem.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 115adde76a..270765e064 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -1652,6 +1652,8 @@ def _normalize_sam_product_names(names): Replace special characters within the product names to make them more suitable fur use as Dataframe column names. ''' + # Contributed by Anton Driesse (@adriesse), PV Performance Labs. July, 2019 + import warnings BAD_CHARS = ' -.()[]:+/",' From 627be569f04f2edda0b376e94395ecf61ba50915 Mon Sep 17 00:00:00 2001 From: Anton Driesse Date: Wed, 27 Nov 2019 20:54:29 +0100 Subject: [PATCH 4/4] u -> o --- pvlib/pvsystem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 270765e064..fac828fa0a 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -1650,7 +1650,7 @@ def retrieve_sam(name=None, path=None): def _normalize_sam_product_names(names): ''' Replace special characters within the product names to make them more - suitable fur use as Dataframe column names. + suitable for use as Dataframe column names. ''' # Contributed by Anton Driesse (@adriesse), PV Performance Labs. July, 2019