Repository: statsmodels/statsmodels

Issue:
The xvals arg in smoothers_lowess gets ValueError
#### Describe the bug
xvals arg in statsmodels.nonparametric.smoothers_lowess.lowess gets ValueError
The function works fine when xvals=None, but raises this ValueError on any xval value, regardless what data type is supplied.

#### Code Sample, a copy-pastable example if possible

```
python3
Python 3.7.4 (default, Nov  2 2019, 13:31:25) 
[Clang 10.0.1 (clang-1001.0.46.4)] on darwin

>>> import statsmodels
>>> statsmodels.__version__
'0.13.1'

>>> import numpy as np

>>> from statsmodels.nonparametric.smoothers_lowess import lowess

>>> np.ascontiguousarray(xvals)
array([ 6, 24, 25, 35, 31, 37, 38, 38, 38, 38, 39])
>>> 
>>> ff = lowess(yy3, xx3, frac= .2, it=1, xvals=None)
>>> 
>>> ff = lowess(yy3, xx3, frac= .2, it=1, xvals=yy3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/shuzhao/.pyenv/versions/3.7.4/lib/python3.7/site-packages/statsmodels/nonparametric/smoothers_lowess.py", line 241, in lowess
    frac=frac, it=0, delta=delta, given_xvals=True)
  File "statsmodels/nonparametric/_smoothers_lowess.pyx", line 24, in statsmodels.nonparametric._smoothers_lowess.lowess
ValueError: Buffer dtype mismatch, expected 'DTYPE_t' but got 'long'

```




Discussion:
Cast your array to floats.


Resolving patch:
diff --git a/statsmodels/nonparametric/smoothers_lowess.py b/statsmodels/nonparametric/smoothers_lowess.py
--- a/statsmodels/nonparametric/smoothers_lowess.py
+++ b/statsmodels/nonparametric/smoothers_lowess.py
@@ -234,7 +234,7 @@ def lowess(endog, exog, frac=2.0/3.0, it=3, delta=0.0, xvals=None, is_sorted=Fal
                                 frac=frac, it=it-1, delta=delta, given_xvals=False)
         else:
             weights = np.ones_like(x)
-        xvalues = np.ascontiguousarray(xvalues)
+        xvalues = np.ascontiguousarray(xvalues, dtype=float)
         # Then run once more using those supplied weights at the points provided by xvals
         # No extra iterations are performed here since weights are fixed
         res, _ = _lowess(y, x, xvalues, weights,


Test patch:
diff --git a/statsmodels/nonparametric/tests/test_lowess.py b/statsmodels/nonparametric/tests/test_lowess.py
--- a/statsmodels/nonparametric/tests/test_lowess.py
+++ b/statsmodels/nonparametric/tests/test_lowess.py
@@ -12,13 +12,14 @@
 import os
 
 import numpy as np
-import pytest
 from numpy.testing import (
-    assert_almost_equal,
     assert_,
-    assert_raises,
+    assert_allclose,
+    assert_almost_equal,
     assert_equal,
+    assert_raises,
 )
+import pytest
 
 from statsmodels.nonparametric.smoothers_lowess import lowess
 
@@ -227,7 +228,8 @@ def test_duplicate_xs(self):
 
     def test_spike(self):
         # see 7700
-        # Create a curve that is easy to fit at first but gets harder further along.
+        # Create a curve that is easy to fit at first but gets
+        # harder further along.
         # This used to give an outlier bad fit at position 961
         x = np.linspace(0, 10, 1001)
         y = np.cos(x ** 2 / 5)
@@ -285,3 +287,11 @@ def test_returns_inputs():
     x = np.arange(20)
     result = lowess(y, x, frac=0.4)
     assert_almost_equal(result, np.column_stack((x, y)))
+
+
+def test_xvals_dtype(reset_randomstate):
+    y = [0] * 10 + [1] * 10
+    x = np.arange(20)
+    # Previously raised ValueError: Buffer dtype mismatch
+    results_xvals = lowess(y, x, frac=0.4, xvals=x[:5])
+    assert_allclose(results_xvals, np.zeros(5), atol=1e-12)