diff --git a/docs/sphinx/source/whatsnew/v0.15.3.rst b/docs/sphinx/source/whatsnew/v0.15.3.rst index b79b9aed66..9d626c6fb1 100644 --- a/docs/sphinx/source/whatsnew/v0.15.3.rst +++ b/docs/sphinx/source/whatsnew/v0.15.3.rst @@ -13,7 +13,11 @@ Deprecations Bug fixes -~~~~~~~~~ +~~~~~~~~ + +* Fixed ``irradiance.dirint`` so that an interior missing value in the input + series no longer halves the single valid neighbor difference when computing + the stability index ``delta_kt_prime`` (Perez eqn 3). (:issue:`1847`) Enhancements @@ -53,4 +57,5 @@ Contributors * Karl Hill (:ghuser:`karlhillx`) * Mathias Aschwanden (:ghuser:`maschwanden`) * Yonry Zhu (:ghuser:`yonryzhu`) +* Aditya (:ghuser:`adi-IL`) * Darshan Gowda (:ghuser:`dgowdaan-cmyk`) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 98bd948286..622f4303e6 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -2035,16 +2035,14 @@ def _delta_kt_prime_dirint(kt_prime, use_delta_kt_prime, times): for use with :py:func:`_dirint_bins`. """ if use_delta_kt_prime: - # Perez eqn 2 + # row-wise mean of neighbor abs-differences; pandas skips NaN so this + # covers 0/1/2 valid neighbors (Perez eqn 2 interior, eqn 3 boundary/gap) kt_next = kt_prime.shift(-1) kt_previous = kt_prime.shift(1) - # replace nan with values that implement Perez Eq 3 for first and last - # positions. Use kt_previous and kt_next to handle series of length 1 - kt_next.iloc[-1] = kt_previous.iloc[-1] - kt_previous.iloc[0] = kt_next.iloc[0] - delta_kt_prime = 0.5 * ((kt_prime - kt_next).abs().add( - (kt_prime - kt_previous).abs(), - fill_value=0)) + delta_kt_prime = pd.DataFrame({ + 'next': (kt_prime - kt_next).abs(), + 'prev': (kt_prime - kt_previous).abs(), + }).mean(axis=1) else: # do not change unless also modifying _dirint_bins delta_kt_prime = pd.Series(-1, index=times) diff --git a/tests/test_irradiance.py b/tests/test_irradiance.py index fbe9906358..cbb24fe4d6 100644 --- a/tests/test_irradiance.py +++ b/tests/test_irradiance.py @@ -719,6 +719,17 @@ def test_dirint_nans(): np.array([np.nan, np.nan, np.nan, np.nan, 893.1]), 1) +def test_delta_kt_prime_interior_nan(): + # regression test for gh-1847: an interior NaN in kt_prime must not + # halve the single valid neighbor difference. When only one neighbor + # is available (Perez eqn 3) delta_kt_prime equals that difference. + times = pd.date_range(start='2020-01-01', periods=5, freq='1h') + kt_prime = pd.Series([0.5, 0.6, np.nan, 0.7, 0.4], index=times) + result = irradiance._delta_kt_prime_dirint(kt_prime, True, times) + expected = pd.Series([0.1, 0.1, np.nan, 0.3, 0.3], index=times) + assert_series_equal(result, expected) + + def test_dirint_tdew(): times = pd.DatetimeIndex(['2014-06-24T12-0700', '2014-06-24T18-0700']) ghi = pd.Series([1038.62, 254.53], index=times)