Repository: pandas-dev/pandas

Issue:
astype(np.int32) converts np.inf to int32 min value
It seems that converting np.inf to int32 and int64 using pd.astype converts them to the min int value rather than throwing an exception.  Presumably this is because they raise OverflowError and not ValueError
#### Code Sample, a copy-pastable example if possible

```
for typ in [np.int32, np.int64]:
    for badval in [np.nan, np.inf]:
        # Print the exception thrown by casting to numpy directly
        try:
            typ(badval)
        except Exception as e:
            print "np.%s(np.%s) throws %s: %s" % (typ.__name__, badval, type(e).__name__, e)

        # Print the exception or resulting value by casting using pd.astype
        try:
            typed = pd.Series([badval]).astype(typ)
            print "pd.Series([np.%s]).astype(np.%s) returns dataframe containing %s" % (badval, typ.__name__, typed[0])
            print "Returned DataFrame:"
            print typed
        except Exception as e:
            print "pd.Series([np.%s]).astype(np.%s) throws %s: %s" % (badval, typ.__name__, type(e).__name__, e)

        print ""
```
#### Expected Output

```
np.int32(np.nan) throws ValueError: cannot convert float NaN to integer
pd.Series([np.nan]).astype(np.int32) throws ValueError: Cannot convert NA to integer

np.int32(np.inf) throws OverflowError: cannot convert float infinity to integer
pd.Series([np.inf]).astype(np.int32) returns dataframe containing -2147483648
Returned DataFrame:
0   -2147483648
dtype: int32

np.int64(np.nan) throws ValueError: cannot convert float NaN to integer
pd.Series([np.nan]).astype(np.int64) throws ValueError: Cannot convert NA to integer

np.int64(np.inf) throws OverflowError: cannot convert float infinity to integer
pd.Series([np.inf]).astype(np.int64) returns dataframe containing -9223372036854775808
Returned DataFrame:
0   -9223372036854775808
dtype: int64
```
#### output of `pd.show_versions()`

```
INSTALLED VERSIONS
------------------
commit: None
python: 2.7.12.final.0
python-bits: 64
OS: Linux
OS-release: 4.0.9-63_fbk11_3989_g7d5ca22
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8

pandas: 0.18.1
nose: 1.3.4
pip: 8.1.2
setuptools: 25.1.6
Cython: 0.22
numpy: 1.11.1
scipy: 0.18.0
statsmodels: 0.6.1
xarray: None
IPython: 5.0.0
sphinx: 1.2.3
patsy: 0.3.0
dateutil: 2.4.1
pytz: 2015.2
blosc: None
bottleneck: None
tables: 3.1.1
numexpr: 2.6.1
matplotlib: 1.4.3
openpyxl: 1.8.5
xlrd: 0.9.3
xlwt: 0.7.5
xlsxwriter: 0.6.7
lxml: 3.4.2
bs4: 4.3.2
html5lib: None
httplib2: None
apiclient: None
sqlalchemy: 0.9.9
pymysql: None
psycopg2: None
jinja2: 2.8
boto: 2.36.0
pandas_datareader: None
```



Discussion:
to be honest this is not a pandas issue and a numpy issue. though I suppose we could intercept / fix this.

Encountered this once in my own work and thought I'd close it up with a PR. 


Resolving patch:
diff --git a/pandas/types/cast.py b/pandas/types/cast.py
--- a/pandas/types/cast.py
+++ b/pandas/types/cast.py
@@ -527,8 +527,10 @@ def _astype_nansafe(arr, dtype, copy=True):
     elif (np.issubdtype(arr.dtype, np.floating) and
           np.issubdtype(dtype, np.integer)):
 
-        if np.isnan(arr).any():
-            raise ValueError('Cannot convert NA to integer')
+        if not np.isfinite(arr).all():
+            raise ValueError('Cannot convert non-finite values (NA or inf) to '
+                             'integer')
+
     elif arr.dtype == np.object_ and np.issubdtype(dtype.type, np.integer):
         # work around NumPy brokenness, #1987
         return lib.astype_intsafe(arr.ravel(), dtype).reshape(arr.shape)


Test patch:
diff --git a/pandas/sparse/tests/test_array.py b/pandas/sparse/tests/test_array.py
--- a/pandas/sparse/tests/test_array.py
+++ b/pandas/sparse/tests/test_array.py
@@ -361,7 +361,7 @@ def test_astype(self):
             arr.astype('i8')
 
         arr = SparseArray([0, np.nan, 0, 1], fill_value=0)
-        msg = "Cannot convert NA to integer"
+        msg = 'Cannot convert non-finite values \(NA or inf\) to integer'
         with tm.assertRaisesRegexp(ValueError, msg):
             arr.astype('i8')
 
diff --git a/pandas/tests/frame/test_dtypes.py b/pandas/tests/frame/test_dtypes.py
--- a/pandas/tests/frame/test_dtypes.py
+++ b/pandas/tests/frame/test_dtypes.py
@@ -353,9 +353,17 @@ def test_astype_with_view(self):
         tf = self.frame.astype(np.float64)
         casted = tf.astype(np.int64, copy=False)  # noqa
 
-    def test_astype_cast_nan_int(self):
-        df = DataFrame(data={"Values": [1.0, 2.0, 3.0, np.nan]})
-        self.assertRaises(ValueError, df.astype, np.int64)
+    def test_astype_cast_nan_inf_int(self):
+        # GH14265, check nan and inf raise error when converting to int
+        types = [np.int32, np.int64]
+        values = [np.nan, np.inf]
+        msg = 'Cannot convert non-finite values \(NA or inf\) to integer'
+
+        for this_type in types:
+            for this_val in values:
+                df = DataFrame([this_val])
+                with tm.assertRaisesRegexp(ValueError, msg):
+                    df.astype(this_type)
 
     def test_astype_str(self):
         # GH9757
diff --git a/pandas/tests/series/test_dtypes.py b/pandas/tests/series/test_dtypes.py
--- a/pandas/tests/series/test_dtypes.py
+++ b/pandas/tests/series/test_dtypes.py
@@ -42,9 +42,17 @@ def test_dtype(self):
         assert_series_equal(self.ts.get_ftype_counts(), Series(
             1, ['float64:dense']))
 
-    def test_astype_cast_nan_int(self):
-        df = Series([1.0, 2.0, 3.0, np.nan])
-        self.assertRaises(ValueError, df.astype, np.int64)
+    def test_astype_cast_nan_inf_int(self):
+        # GH14265, check nan and inf raise error when converting to int
+        types = [np.int32, np.int64]
+        values = [np.nan, np.inf]
+        msg = 'Cannot convert non-finite values \(NA or inf\) to integer'
+
+        for this_type in types:
+            for this_val in values:
+                s = Series([this_val])
+                with self.assertRaisesRegexp(ValueError, msg):
+                    s.astype(this_type)
 
     def test_astype_cast_object_int(self):
         arr = Series(["car", "house", "tree", "1"])