Repository: statsmodels/statsmodels (python)

Issue:
Multi-dimensional indexing error in statsmodels.stats.diagnostic.linear_reset when using Pandas
#### Describe the bug

I tried to do a linear RESET test, but I got an error: `ValueError: Multi-dimensional indexing (e.g. `obj[:, None]`) is no longer supported. Convert to a numpy array before indexing instead.`

Complete error message down below.

#### Code Sample, a copy-pastable example if possible


```python
#!/usr/bin/env python3
import numpy as np
import pandas as pd
import statsmodels.stats.diagnostic as smdiag
import statsmodels.api as sm

n = 100

df = pd.DataFrame()

df["y"] = np.random.rand(n)
df["x"] = np.random.rand(n)

OLS_results = sm.OLS(df["y"], df["x"]).fit()

smdiag.linear_reset(OLS_results)
```
<details>

Complete error Traceback:
```
Traceback (most recent call last):
  File "/home/jonathan/RietNAS/Opleiding/EUR/1. Pre-master/FEB22009S Seminar Case Study/bug_report.py", line 16, in <module>
    smdiag.linear_reset(OLS_results)
  File "/home/jonathan/RietNAS/Opleiding/EUR/1. Pre-master/FEB22009S Seminar Case Study/.venv/lib/python3.10/site-packages/pandas/util/_decorators.py", line 210, in wrapper
    return func(*args, **kwargs)
  File "/home/jonathan/RietNAS/Opleiding/EUR/1. Pre-master/FEB22009S Seminar Case Study/.venv/lib/python3.10/site-packages/statsmodels/stats/diagnostic.py", line 1065, in linear_reset
    aug = res.fittedvalues[:, None]
  File "/home/jonathan/RietNAS/Opleiding/EUR/1. Pre-master/FEB22009S Seminar Case Study/.venv/lib/python3.10/site-packages/pandas/core/series.py", line 1033, in __getitem__
    return self._get_with(key)
  File "/home/jonathan/RietNAS/Opleiding/EUR/1. Pre-master/FEB22009S Seminar Case Study/.venv/lib/python3.10/site-packages/pandas/core/series.py", line 1048, in _get_with
    return self._get_values_tuple(key)
  File "/home/jonathan/RietNAS/Opleiding/EUR/1. Pre-master/FEB22009S Seminar Case Study/.venv/lib/python3.10/site-packages/pandas/core/series.py", line 1082, in _get_values_tuple
    disallow_ndim_indexing(result)
  File "/home/jonathan/RietNAS/Opleiding/EUR/1. Pre-master/FEB22009S Seminar Case Study/.venv/lib/python3.10/site-packages/pandas/core/indexers/utils.py", line 343, in disallow_ndim_indexing
    raise ValueError(
ValueError: Multi-dimensional indexing (e.g. `obj[:, None]`) is no longer supported. Convert to a numpy array before indexing instead.
```

The error does not occur if `y` and `x` are passed as NumPy arrays, only when passed as pandas dataframe.

Using `statsmodels.stats.outliers_influence.reset_ramsey` also doesn't give this same problem.


</details>


If the issue has not been resolved, please file it in the issue tracker.

#### Expected Output

I expect to get the results of the test, as `statsmodels.stats.outliers_influence import reset_ramsey` does.

#### Output of ``import statsmodels.api as sm; sm.show_versions()``

<details>

[paste the output of ``import statsmodels.api as sm; sm.show_versions()`` here below this line]
INSTALLED VERSIONS
------------------
Python: 3.10.6.final.0
OS: Linux 6.2.6-76060206-generic #202303130630~1681329778~22.04~d824cd4 SMP PREEMPT_DYNAMIC Wed A x86_64
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8

statsmodels
===========

Installed: 0.14.0 (/home/jonathan/RietNAS/Opleiding/EUR/1. Pre-master/FEB22009S Seminar Case Study/.venv/lib/python3.10/site-packages/statsmodels)

Required Dependencies
=====================

cython: Not installed
numpy: 1.24.3 (/home/jonathan/RietNAS/Opleiding/EUR/1. Pre-master/FEB22009S Seminar Case Study/.venv/lib/python3.10/site-packages/numpy)
scipy: 1.10.1 (/home/jonathan/RietNAS/Opleiding/EUR/1. Pre-master/FEB22009S Seminar Case Study/.venv/lib/python3.10/site-packages/scipy)
pandas: 2.0.1 (/home/jonathan/RietNAS/Opleiding/EUR/1. Pre-master/FEB22009S Seminar Case Study/.venv/lib/python3.10/site-packages/pandas)
    dateutil: 2.8.2 (/home/jonathan/RietNAS/Opleiding/EUR/1. Pre-master/FEB22009S Seminar Case Study/.venv/lib/python3.10/site-packages/dateutil)
patsy: 0.5.3 (/home/jonathan/RietNAS/Opleiding/EUR/1. Pre-master/FEB22009S Seminar Case Study/.venv/lib/python3.10/site-packages/patsy)

Optional Dependencies
=====================

matplotlib: 3.7.1 (/home/jonathan/RietNAS/Opleiding/EUR/1. Pre-master/FEB22009S Seminar Case Study/.venv/lib/python3.10/site-packages/matplotlib)
    backend: agg 
cvxopt: Not installed
joblib: 1.2.0 (/home/jonathan/RietNAS/Opleiding/EUR/1. Pre-master/FEB22009S Seminar Case Study/.venv/lib/python3.10/site-packages/joblib)

Developer Tools
================

IPython: 8.13.2 (/home/jonathan/RietNAS/Opleiding/EUR/1. Pre-master/FEB22009S Seminar Case Study/.venv/lib/python3.10/site-packages/IPython)
    jinja2: Not installed
sphinx: Not installed
    pygments: 2.15.1 (/home/jonathan/RietNAS/Opleiding/EUR/1. Pre-master/FEB22009S Seminar Case Study/.venv/lib/python3.10/site-packages/pygments)
pytest: Not installed
virtualenv: Not installed

</details>


Pull request:
BUG: Correct diagnostics for changes in pandas
Fix issues related to multi-dimensional indexing in pandas

closes #8879

- [X] closes #8879
- [X] tests added / passed. 
- [X] code/documentation is well formatted.  
- [X] properly formatted commit message. See 
      [NumPy's guide](https://docs.scipy.org/doc/numpy-1.15.1/dev/gitwash/development_workflow.html#writing-the-commit-message). 

<details>


**Notes**:

* It is essential that you add a test when making code changes. Tests are not 
  needed for doc changes.
* When adding a new function, test values should usually be verified in another package (e.g., R/SAS/Stata).
* When fixing a bug, you must add a test that would produce the bug in main and
  then show that it is fixed with the new code.
* New code additions must be well formatted. Changes should pass flake8. If on Linux or OSX, you can
  verify you changes are well formatted by running 
  ```
  git diff upstream/main -u -- "*.py" | flake8 --diff --isolated
  ```
  assuming `flake8` is installed. This command is also available on Windows 
  using the Windows System for Linux once `flake8` is installed in the 
  local Linux environment. While passing this test is not required, it is good practice and it help 
  improve code quality in `statsmodels`.
* Docstring additions must render correctly, including escapes and LaTeX.

</details>


Patch:
diff --git a/setup.cfg b/setup.cfg
index 5b3030faf..f18bd97ff 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -91,6 +91,8 @@ filterwarnings =
     error:The previous implementation of stack is deprecated:FutureWarning
     error:Series.__setitem__ treating keys as positions is deprecated:FutureWarning
     error:The provided callable:FutureWarning
+    error:divide by zero encountered in log1p:RuntimeWarning
+
 markers =
     example: mark a test that runs example code
     matplotlib: mark a test that requires matplotlib
diff --git a/statsmodels/graphics/tsaplots.py b/statsmodels/graphics/tsaplots.py
index c3358cd28..ddeec5293 100644
--- a/statsmodels/graphics/tsaplots.py
+++ b/statsmodels/graphics/tsaplots.py
@@ -17,7 +17,7 @@ def _prepare_data_corr_plot(x, lags, zero):
     if lags is None:
         # GH 4663 - use a sensible default value
         nobs = x.shape[0]
-        lim = min(int(np.ceil(10 * np.log10(nobs))), nobs // 2)
+        lim = min(int(np.ceil(10 * np.log10(nobs))), nobs - 1)
         lags = np.arange(not zero, lim + 1)
     elif np.isscalar(lags):
         lags = np.arange(not zero, int(lags) + 1)  # +1 for zero lag
diff --git a/statsmodels/stats/_adnorm.py b/statsmodels/stats/_adnorm.py
index 05b01620b..bed38c4fd 100644
--- a/statsmodels/stats/_adnorm.py
+++ b/statsmodels/stats/_adnorm.py
@@ -5,6 +5,8 @@ Created on Sun Sep 25 21:23:38 2011
 Author: Josef Perktold and Scipy developers
 License : BSD-3
 """
+import warnings
+
 import numpy as np
 from scipy import stats
 
@@ -64,8 +66,12 @@ def anderson_statistic(x, dist='norm', fit=True, params=(), axis=0):
     sl2 = [slice(None)] * x.ndim
     sl2[axis] = slice(None, None, -1)
     sl2 = tuple(sl2)
-    s = np.sum((2 * i[sl1] - 1.0) / nobs * (np.log(z) + np.log1p(-z[sl2])),
-               axis=axis)
+    with warnings.catch_warnings():
+        warnings.filterwarnings(
+            "ignore", message="divide by zero encountered in log1p"
+        )
+        ad_values = (2 * i[sl1] - 1.0) / nobs * (np.log(z) + np.log1p(-z[sl2]))
+        s = np.sum(ad_values, axis=axis)
     a2 = -nobs - s
     return a2
 
diff --git a/statsmodels/stats/diagnostic.py b/statsmodels/stats/diagnostic.py
index 9c4a577f8..07c1c4ecd 100644
--- a/statsmodels/stats/diagnostic.py
+++ b/statsmodels/stats/diagnostic.py
@@ -1072,7 +1072,7 @@ def linear_reset(res, power=3, test_type="fitted", use_f=False,
             raise ValueError("power must contains distinct integers all >= 2")
     exog = res.model.exog
     if test_type == "fitted":
-        aug = res.fittedvalues[:, None]
+        aug = np.asarray(res.fittedvalues)[:, None]
     elif test_type == "exog":
         # Remove constant and binary
         aug = res.model.exog
@@ -1293,7 +1293,7 @@ def linear_lm(resid, exog, func=None):
     if func is None:
         def func(x):
             return np.power(x, 2)
-
+    exog = np.asarray(exog)
     exog_aux = np.column_stack((exog, func(exog[:, 1:])))
 
     nobs, k_vars = exog.shape
diff --git a/statsmodels/tsa/stattools.py b/statsmodels/tsa/stattools.py
index 891c77634..6b30f2173 100644
--- a/statsmodels/tsa/stattools.py
+++ b/statsmodels/tsa/stattools.py
@@ -8,7 +8,7 @@ from statsmodels.compat.pandas import deprecate_kwarg
 from statsmodels.compat.python import Literal, lzip
 from statsmodels.compat.scipy import _next_regular
 
-from typing import Union, List
+from typing import Tuple
 import warnings
 
 import numpy as np
@@ -40,8 +40,6 @@ from statsmodels.tsa._innovations import innovations_algo, innovations_filter
 from statsmodels.tsa.adfvalues import mackinnoncrit, mackinnonp
 from statsmodels.tsa.tsatools import add_trend, lagmat, lagmat2ds
 
-ArrayLike1D = Union[np.ndarray, pd.Series, List[float]]
-
 __all__ = [
     "acovf",
     "acf",
@@ -711,11 +709,8 @@ def acf(
     else:
         return acf, qstat, pvalue
 
-def pacf_yw(
-    x: ArrayLike1D,
-    nlags: int | None = None,
-    method: Literal["adjusted", "mle"] = "adjusted",
-) -> np.ndarray:
+
+def pacf_yw(x, nlags=None, method="adjusted"):
     """
     Partial autocorrelation estimated with non-recursive yule_walker.
 
@@ -752,7 +747,8 @@ def pacf_yw(
     nlags = int_like(nlags, "nlags", optional=True)
     nobs = x.shape[0]
     if nlags is None:
-        nlags = max(min(int(10 * np.log10(nobs)), nobs - 1), 1)
+        nlags = min(int(10 * np.log10(nobs)), nobs - 1)
+
     method = string_like(method, "method", options=("adjusted", "mle"))
     pacf = [1.0]
     with warnings.catch_warnings():
@@ -762,9 +758,7 @@ def pacf_yw(
     return np.array(pacf)
 
 
-def pacf_burg(
-    x: ArrayLike1D, nlags: int | None = None, demean: bool = True
-) -> tuple[np.ndarray, np.ndarray]:
+def pacf_burg(x, nlags=None, demean=True):
     """
     Calculate Burg"s partial autocorrelation estimator.
 
@@ -806,7 +800,6 @@ def pacf_burg(
         x = x - x.mean()
     nobs = x.shape[0]
     p = nlags if nlags is not None else min(int(10 * np.log10(nobs)), nobs - 1)
-    p = max(p, 1)
     if p > nobs - 1:
         raise ValueError("nlags must be smaller than nobs - 1")
     d = np.zeros(p + 1)
@@ -825,19 +818,14 @@ def pacf_burg(
         v[1:] = last_v[1:] - pacf[i] * last_u[:-1]
         d[i + 1] = (1 - pacf[i] ** 2) * d[i] - v[i] ** 2 - u[-1] ** 2
         pacf[i + 1] = 2 / d[i + 1] * v[i + 1 :].dot(u[i:-1])
-    sigma2 = (1 - pacf**2) * d / (2.0 * (nobs - np.arange(0, p + 1)))
+    sigma2 = (1 - pacf ** 2) * d / (2.0 * (nobs - np.arange(0, p + 1)))
     pacf[0] = 1  # Insert the 0 lag partial autocorrel
 
     return pacf, sigma2
 
 
 @deprecate_kwarg("unbiased", "adjusted")
-def pacf_ols(
-    x: ArrayLike1D,
-    nlags: int | None = None,
-    efficient: bool = True,
-    adjusted: bool = False,
-) -> np.ndarray:
+def pacf_ols(x, nlags=None, efficient=True, adjusted=False):
     """
     Calculate partial autocorrelations via OLS.
 
@@ -897,9 +885,8 @@ def pacf_ols(
     adjusted = bool_like(adjusted, "adjusted")
     nobs = x.shape[0]
     if nlags is None:
-        nlags = max(min(int(10 * np.log10(nobs)), nobs // 2), 1)
-    if nlags > nobs//2:
-        raise ValueError(f"nlags must be smaller than nobs // 2 ({nobs//2})")
+        nlags = min(int(10 * np.log10(nobs)), nobs - 1)
+
     pacf = np.empty(nlags + 1)
     pacf[0] = 1.0
     if efficient:
@@ -916,30 +903,14 @@ def pacf_ols(
             params = lstsq(xlags[:, :k], x0, rcond=None)[0]
             # Last coefficient corresponds to PACF value (see [1])
             pacf[k] = np.squeeze(params[-1])
+
     if adjusted:
         pacf *= nobs / (nobs - np.arange(nlags + 1))
+
     return pacf
 
 
-def pacf(
-    x: ArrayLike1D,
-    nlags: int | None = None,
-    method: Literal[
-        "yw",
-        "ywadjusted",
-        "ols",
-        "ols-inefficient",
-        "ols-adjusted",
-        "ywm",
-        "ywmle",
-        "ld",
-        "ldadjusted",
-        "ldb",
-        "ldbiased",
-        "burg",
-    ] = "ywadjusted",
-    alpha: float | None = None,
-) -> np.ndarray | tuple[np.ndarray, np.ndarray]:
+def pacf(x, nlags=None, method="ywadjusted", alpha=None):
     """
     Partial autocorrelation estimate.
 
@@ -1025,7 +996,7 @@ def pacf(
         "ldb",
         "ldbiased",
         "ld_biased",
-        "burg",
+        "burg"
     )
     x = array_like(x, "x", maxdim=2)
     method = string_like(method, "method", options=methods)
@@ -1034,13 +1005,13 @@ def pacf(
     nobs = x.shape[0]
     if nlags is None:
         nlags = min(int(10 * np.log10(nobs)), nobs // 2 - 1)
-    nlags = max(nlags, 1)
-    if nlags > x.shape[0] // 2:
+    if nlags >= x.shape[0] // 2:
         raise ValueError(
             "Can only compute partial correlations for lags up to 50% of the "
             f"sample size. The requested nlags {nlags} must be < "
             f"{x.shape[0] // 2}."
         )
+
     if method in ("ols", "ols-inefficient", "ols-adjusted"):
         efficient = "inefficient" not in method
         adjusted = "adjusted" in method
@@ -1060,6 +1031,7 @@ def pacf(
         acv = acovf(x, adjusted=False, fft=False)
         ld_ = levinson_durbin(acv, nlags=nlags, isacov=True)
         ret = ld_[2]
+
     if alpha is not None:
         varacf = 1.0 / len(x)  # for all lags >=1
         interval = stats.norm.ppf(1.0 - alpha / 2.0) * np.sqrt(varacf)
@@ -1566,7 +1538,7 @@ def grangercausalitytests(x, maxlag, addconst=True, verbose=None):
     if x.shape[0] <= 3 * maxlag + int(addconst):
         raise ValueError(
             "Insufficient observations. Maximum allowable "
-            "lag is {}".format(int((x.shape[0] - int(addconst)) / 3) - 1)
+            "lag is {0}".format(int((x.shape[0] - int(addconst)) / 3) - 1)
         )
 
     resli = {}
@@ -1973,7 +1945,7 @@ def kpss(
     regression: Literal["c", "ct"] = "c",
     nlags: Literal["auto", "legacy"] | int = "auto",
     store: bool = False,
-) -> tuple[float, float, int, dict[str, float]]:
+) -> Tuple[float, float, int, dict[str, float]]:
     """
     Kwiatkowski-Phillips-Schmidt-Shin test for stationarity.
 
@@ -2060,7 +2032,7 @@ def kpss(
 
     # if m is not one, n != m * n
     if nobs != x.size:
-        raise ValueError(f"x of shape {x.shape} not understood")
+        raise ValueError("x of shape {0} not understood".format(x.shape))
 
     if hypo == "ct":
         # p. 162 Kwiatkowski et al. (1992): y_t = beta * t + r_t + e_t,
@@ -2134,8 +2106,8 @@ look-up table. The actual p-value is {direction} than the p-value returned.
         rstore.nobs = nobs
 
         stationary_type = "level" if hypo == "c" else "trend"
-        rstore.H0 = f"The series is {stationary_type} stationary"
-        rstore.HA = f"The series is not {stationary_type} stationary"
+        rstore.H0 = "The series is {0} stationary".format(stationary_type)
+        rstore.HA = "The series is not {0} stationary".format(stationary_type)
 
         return kpss_stat, p_value, crit_dict, rstore
     else:
@@ -2228,7 +2200,7 @@ def range_unit_root_test(x, store=False):
 
     # if m is not one, n != m * n
     if nobs != x.size:
-        raise ValueError(f"x of shape {x.shape} not understood")
+        raise ValueError("x of shape {0} not understood".format(x.shape))
 
     # Table from [1] has been replicated using 200,000 samples
     # Critical values for new n_obs values have been identified
diff --git a/tools/ci/azure/azure_template_posix.yml b/tools/ci/azure/azure_template_posix.yml
index 73a37c7d6..a98062a2e 100644
--- a/tools/ci/azure/azure_template_posix.yml
+++ b/tools/ci/azure/azure_template_posix.yml
@@ -162,6 +162,8 @@ jobs:
       if [[ ${COVERAGE} == "true" ]]; then
         export COVERAGE_OPTS="--cov-config .coveragerc --cov=statsmodels --cov-report xml:coverage.xml --cov-report term"
       fi
+      echo pytest --help
+      pytest --help
       echo pytest -m "${PYTEST_PATTERN}" --skip-examples --junitxml=junit/test-results.xml -n auto --dist loadscope --durations=25 ${COVERAGE_OPTS} statsmodels
       pytest -m "${PYTEST_PATTERN}" --skip-examples --junitxml=junit/test-results.xml -n auto --dist loadscope --durations=25 ${COVERAGE_OPTS} statsmodels
     displayName: 'Run tests (pip pre)'


Test patch:
diff --git a/statsmodels/graphics/tests/test_tsaplots.py b/statsmodels/graphics/tests/test_tsaplots.py
index 5ba24f02a..44c1b49d0 100644
--- a/statsmodels/graphics/tests/test_tsaplots.py
+++ b/statsmodels/graphics/tests/test_tsaplots.py
@@ -375,14 +375,3 @@ def test_predict_plot(use_pandas, model_and_args, alpha):
     res = model(y, **kwargs).fit()
     fig = plot_predict(res, start, end, alpha=alpha)
     assert isinstance(fig, plt.Figure)
-
-
-@pytest.mark.matplotlib
-def test_plot_pacf_small_sample():
-    idx = [pd.Timestamp.now() + pd.Timedelta(seconds=i) for i in range(10)]
-    df = pd.DataFrame(
-        index=idx,
-        columns=["a"],
-        data=list(range(10))
-    )
-    plot_pacf(df)
diff --git a/statsmodels/stats/tests/test_diagnostic.py b/statsmodels/stats/tests/test_diagnostic.py
index b1f803ed7..b05698e64 100644
--- a/statsmodels/stats/tests/test_diagnostic.py
+++ b/statsmodels/stats/tests/test_diagnostic.py
@@ -1957,3 +1957,43 @@ def test_small_skip(reset_randomstate):
 # M2 + fit(M1)-exp(fit(M2)) < 2.22e-16 ***
 # ---
 # Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
+
+@pytest.mark.smoke
+def test_diagnostics_pandas(reset_randomstate):
+    # GH 8879
+    n = 100
+    df = pd.DataFrame(
+        {
+            "y": np.random.rand(n),
+            "x": np.random.rand(n),
+            "z": np.random.rand(n)}
+    )
+    y, x = df["y"], add_constant(df["x"])
+
+    res = OLS(df["y"], add_constant(df[["x"]])).fit()
+    res_large = OLS(df["y"], add_constant(df[["x", "z"]])).fit()
+    res_other = OLS(df["y"], add_constant(df[["z"]])).fit()
+    smsdia.linear_reset(res_large)
+    smsdia.linear_reset(res_large, test_type="fitted")
+    smsdia.linear_reset(res_large, test_type="exog")
+    smsdia.linear_reset(res_large, test_type="princomp")
+    smsdia.het_goldfeldquandt(y, x)
+    smsdia.het_breuschpagan(res.resid, x)
+    smsdia.het_white(res.resid, x)
+    smsdia.het_arch(res.resid)
+    smsdia.acorr_breusch_godfrey(res)
+    smsdia.acorr_ljungbox(y)
+    smsdia.linear_rainbow(res)
+    smsdia.linear_lm(res.resid, x)
+    smsdia.linear_harvey_collier(res)
+    smsdia.acorr_lm(res.resid)
+    smsdia.breaks_cusumolsresid(res.resid)
+    smsdia.breaks_hansen(res)
+    smsdia.compare_cox(res, res_other)
+    smsdia.compare_encompassing(res, res_other)
+    smsdia.compare_j(res, res_other)
+    smsdia.recursive_olsresiduals(res)
+    smsdia.recursive_olsresiduals(
+        res, order_by=np.arange(y.shape[0] - 1, 0 - 1, -1)
+    )
+    smsdia.spec_white(res.resid, x)
diff --git a/statsmodels/tsa/statespace/tests/results/results_structural.py b/statsmodels/tsa/statespace/tests/results/results_structural.py
index 53c8e2c30..61e35801a 100644
--- a/statsmodels/tsa/statespace/tests/results/results_structural.py
+++ b/statsmodels/tsa/statespace/tests/results/results_structural.py
@@ -283,7 +283,7 @@ lltrend_cycle_seasonal_reg_ar1_approx_diffuse = {
         # Annual frequency dataset
         {'level': 'lltrend', 'autoregressive': 1, 'cycle': True,
          'stochastic_cycle': True, 'seasonal': 4, 'autoregressive': 1,
-         'exog': True, 'mle_regression': False, 'freq': 'YS'},
+         'exog': True, 'mle_regression': False, 'freq': 'AS'},
         # Quarterly frequency dataset
         {'level': 'lltrend', 'autoregressive': 1, 'cycle': True,
          'stochastic_cycle': True, 'seasonal': 4, 'autoregressive': 1,
@@ -295,7 +295,7 @@ lltrend_cycle_seasonal_reg_ar1_approx_diffuse = {
         # Minutely frequency dataset
         {'level': 'lltrend', 'autoregressive': 1, 'cycle': True,
          'stochastic_cycle': True, 'seasonal': 4, 'autoregressive': 1,
-         'exog': True, 'mle_regression': False, 'freq': 'min',
+         'exog': True, 'mle_regression': False, 'freq': 'T',
          'cycle_period_bounds': (1.5*12, 12*12)},
     ],
     'params': [0.0001, 0.01, 0.06, 0.0001, 0.0001, 0.1, 2*pi / 10, 0.2],
diff --git a/statsmodels/tsa/statespace/tests/test_structural.py b/statsmodels/tsa/statespace/tests/test_structural.py
index e27102bad..f7ceea3aa 100644
--- a/statsmodels/tsa/statespace/tests/test_structural.py
+++ b/statsmodels/tsa/statespace/tests/test_structural.py
@@ -66,7 +66,7 @@ def run_ucm(name, use_exact_diffuse=False):
         freqstr = freq[0] if freq is not None else values.index.freqstr[0]
         if 'cycle_period_bounds' in kwargs:
             cycle_period_bounds = kwargs['cycle_period_bounds']
-        elif freqstr in ('A', 'AS', 'Y', 'YS'):
+        elif freqstr in ('A', 'AS'):
             cycle_period_bounds = (1.5, 12)
         elif freqstr in ('Q', 'QS'):
             cycle_period_bounds = (1.5*4, 12*4)
diff --git a/statsmodels/tsa/tests/test_stattools.py b/statsmodels/tsa/tests/test_stattools.py
index abbc07181..720e2bedb 100644
--- a/statsmodels/tsa/tests/test_stattools.py
+++ b/statsmodels/tsa/tests/test_stattools.py
@@ -1533,7 +1533,7 @@ def test_acf_conservate_nanops(reset_randomstate):
 
 
 def test_pacf_nlags_error(reset_randomstate):
-    e = np.random.standard_normal(99)
+    e = np.random.standard_normal(100)
     with pytest.raises(ValueError, match="Can only compute partial"):
         pacf(e, 50)
 
@@ -1584,27 +1584,3 @@ def test_granger_causality_exception_maxlag(gc_data):
 def test_granger_causality_verbose(gc_data):
     with pytest.warns(FutureWarning, match="verbose"):
         grangercausalitytests(gc_data, 3, verbose=True)
-
-@pytest.mark.parametrize("size",[3,5,7,9])
-def test_pacf_small_sample(size,reset_randomstate):
-    y = np.random.standard_normal(size)
-    a = pacf(y)
-    assert isinstance(a, np.ndarray)
-    a, b = pacf_burg(y)
-    assert isinstance(a, np.ndarray)
-    assert isinstance(b, np.ndarray)
-    a = pacf_ols(y)
-    assert isinstance(a, np.ndarray)
-    a = pacf_yw(y)
-    assert isinstance(a, np.ndarray)
-
-
-def test_pacf_1_obs(reset_randomstate):
-    y = np.random.standard_normal(1)
-    with pytest.raises(ValueError):
-        pacf(y)
-    with pytest.raises(ValueError):
-        pacf_burg(y)
-    with pytest.raises(ValueError):
-        pacf_ols(y)
-    pacf_yw(y)