Skip to content

Commit

Permalink
ENH: Return column information in add_constant
Browse files Browse the repository at this point in the history
Return information about constant columns in add_constant

closes #6756
  • Loading branch information
Kevin Sheppard committed Jun 28, 2020
1 parent f196c09 commit 72e735a
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 5 deletions.
10 changes: 8 additions & 2 deletions statsmodels/tools/tools.py
Expand Up @@ -317,7 +317,8 @@ def add_constant(data, prepend=True, has_constant='skip'):

# Special case for NumPy
x = np.asanyarray(data)
if x.ndim == 1:
ndim = x.ndim
if ndim == 1:
x = x[:, None]
elif x.ndim > 2:
raise ValueError('Only implemented for 2-dimensional arrays')
Expand All @@ -328,7 +329,12 @@ def add_constant(data, prepend=True, has_constant='skip'):
if has_constant == 'skip':
return x
elif has_constant == 'raise':
raise ValueError("data already contains a constant")
if ndim == 1:
raise ValueError("data is constant.")
else:
columns = np.arange(x.shape[1])
cols = ",".join([str(c) for c in columns[is_nonzero_const]])
raise ValueError(f"Column(s) {cols} are constant.")

x = [np.ones(x.shape[0]), x]
x = x if prepend else x[::-1]
Expand Down
2 changes: 1 addition & 1 deletion statsmodels/tsa/tests/test_arima.py
Expand Up @@ -2580,7 +2580,7 @@ def test_constant_column_trend():
model = ARIMA(endog=endog, order=(1, 1, 0), exog=exog)

# Fitting with a constant and constant exog raises because of colinearity
with pytest.raises(ValueError, match="x contains a constant"):
with pytest.raises(ValueError, match="x contains one or more constant"):
model.fit(trend="c", disp=-1)

# FIXME: calling model.fit(trend="nc") raises for orthogonal reasons
Expand Down
16 changes: 14 additions & 2 deletions statsmodels/tsa/tsatools.py
Expand Up @@ -116,8 +116,20 @@ def safe_is_const(s):

if np.any(col_const):
if has_constant == 'raise':
msg = "x contains a constant. Adding a constant with " \
"trend='{0}' is not allowed.".format(trend)
if x.ndim == 1:
base_err = "x is constant."
else:
columns = np.arange(x.shape[1])[col_const]
if isinstance(x, pd.DataFrame):
columns = x.columns
const_cols = ", ".join([str(c) for c in columns])
base_err = (
"x contains one or more constant columns. Column(s) "
f"{const_cols} are constant."
)
msg = (
f"{base_err} Adding a constant with trend='{trend}' is not allowed."
)
raise ValueError(msg)
elif has_constant == 'skip':
columns = columns[1:]
Expand Down

0 comments on commit 72e735a

Please sign in to comment.