Repository: statsmodels/statsmodels (python)

Issue:
Zivot-Andrews Test with data type float64 modifies dataset used in the test
#### Describe the bug

Using the Zivot-Andrews Test (from statsmodels.tsa.stattools.zivot_andrews) with a variable with type float64 modifies the values of the variable used in the test (in the dataframe). This doesn't happen with variables with type int32, for example.

This is a problem because it changes the values in the dataframe being used for statistical analysis, considering that the Zivot-Andrews test is done before fitting a model.

#### Code Sample, a copy-pastable example if possible


```python
import pandas as pd
import numpy as np
import statsmodels.api as sm
from statsmodels.tsa.stattools import zivot_andrews

sm.show_versions()

# Create a range of years from 1990 to 2023 for the index
years = pd.date_range(start='1990-01-01', end='2023-12-31', freq='AS')
# Create a DataFrame with variable years as the index
df = pd.DataFrame(index=years)
# Set the values for the variable
df['variable1'] = np.where(df.index.year <= 2002, 10, 20)
df['variable2'] = np.where(df.index.year <= 2002, 10, 20)
df.info() 

# Zivot-Andrews test with data with type int32
zivot_andrews(df['variable1'])
zivot_andrews(df['variable1'],regression = 'c')

# Zivot-Andrews test with data with type float64
df=df.astype(float)
zivot_andrews(df['variable1'])
zivot_andrews(df['variable1'],regression = 'c')

```

#### Expected Output

To keep the same dataframe after using the zivot_andrews function.

#### Output of ``import statsmodels.api as sm; sm.show_versions()``

<details>

INSTALLED VERSIONS
------------------
Python: 3.11.5.final.0

statsmodels
===========

Installed: 0.14.0 (C:\ProgramData\anaconda3\Lib\site-packages\statsmodels)

Required Dependencies
=====================

cython: Not installed
numpy: 1.24.3 (C:\ProgramData\anaconda3\Lib\site-packages\numpy)
scipy: 1.11.1 (C:\ProgramData\anaconda3\Lib\site-packages\scipy)
pandas: 2.0.3 (C:\ProgramData\anaconda3\Lib\site-packages\pandas)
    dateutil: 2.8.2 (C:\ProgramData\anaconda3\Lib\site-packages\dateutil)
patsy: 0.5.3 (C:\ProgramData\anaconda3\Lib\site-packages\patsy)

Optional Dependencies
=====================

matplotlib: 3.7.2 (C:\ProgramData\anaconda3\Lib\site-packages\matplotlib)
    backend: module://matplotlib_inline.backend_inline 
cvxopt: Not installed
joblib: 1.2.0 (C:\ProgramData\anaconda3\Lib\site-packages\joblib)

Developer Tools
================

IPython: 8.15.0 (C:\ProgramData\anaconda3\Lib\site-packages\IPython)
    jinja2: 3.1.2 (C:\ProgramData\anaconda3\Lib\site-packages\jinja2)
sphinx: 5.0.2 (C:\ProgramData\anaconda3\Lib\site-packages\sphinx)
    pygments: 2.15.1 (C:\ProgramData\anaconda3\Lib\site-packages\pygments)
pytest: 7.4.0 (C:\ProgramData\anaconda3\Lib\site-packages\pytest)
virtualenv: Not installed

</details>


Pull request description:
BUG: Ensure ZA does not overwrite
Remove use of in-place op
Add test

- [X] closes #9307
- [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/statsmodels/tsa/stattools.py b/statsmodels/tsa/stattools.py
index bfca2fdf2..bc3546db1 100644
--- a/statsmodels/tsa/stattools.py
+++ b/statsmodels/tsa/stattools.py
@@ -2545,7 +2545,7 @@ class ZivotAndrewsUnitRoot:
         # first-diff y and standardize for numerical stability
         endog = np.diff(series, axis=0)
         endog /= np.sqrt(endog.T.dot(endog))
-        series /= np.sqrt(series.T.dot(series))
+        series = series / np.sqrt(series.T.dot(series))
         # reserve exog space
         exog = np.zeros((endog[lags:].shape[0], cols + lags))
         exog[:, 0] = const
@@ -2653,7 +2653,7 @@ class ZivotAndrewsUnitRoot:
            great crash, the oil-price shock, and the unit-root hypothesis.
            Journal of Business & Economic Studies, 10: 251-270.
         """
-        x = array_like(x, "x")
+        x = array_like(x, "x", dtype=np.double, ndim=1)
         trim = float_like(trim, "trim")
         maxlag = int_like(maxlag, "maxlag", optional=True)
         regression = string_like(


Test patch:
diff --git a/statsmodels/tsa/tests/test_stattools.py b/statsmodels/tsa/tests/test_stattools.py
index d910a29db..b9427bad7 100644
--- a/statsmodels/tsa/tests/test_stattools.py
+++ b/statsmodels/tsa/tests/test_stattools.py
@@ -1608,3 +1608,19 @@ def test_pacf_1_obs(reset_randomstate):
     with pytest.raises(ValueError):
         pacf_ols(y)
     pacf_yw(y)
+
+
+def test_zivot_andrews_change_data(reset_randomstate):
+    # GH9307
+    years = pd.date_range(start='1990-01-01', end='2023-12-31', freq='YS')
+    df = pd.DataFrame(index=years)
+    df['variable1'] = np.where(df.index.year <= 2002, 10, 20)
+    df['variable2'] = np.where(df.index.year <= 2002, 10, 20)
+    df.iloc[-1] = 30
+
+    # Zivot-Andrews test with data with type float64
+    df = df.astype(float)
+    df_original = df.copy()
+    zivot_andrews(df['variable1'])
+    zivot_andrews(df['variable1'], regression='c')
+    pd.testing.assert_frame_equal(df, df_original)