Repository: pandas-dev/pandas

Issue:
Raise exception from overflowing uint64 data
ref: http://stackoverflow.com/questions/13550940/python-pandas-insert-long-integer

DataFrame constructor converts uint64 series to object series
#### Code Sample, a copy-pastable example if possible

```python
import pandas as pd
import numpy as np

uint64s = pd.Series([9710005220884355087, 9710005220138399309], dtype=np.dtype('uint64'))
uint64s.dtype  # dtype('uint64')

df = pd.DataFrame({'viadict': uint64s})
df['viacolumn'] = uint64s

df.info()
# Data columns (total 2 columns):
# viadict      2 non-null object
# viacolumn    2 non-null uint64
```
#### Problem description
It seems like these ways of adding columns to a dataframe should have the same behavior.

#### Expected Output
```python
df.info()
# Data columns (total 2 columns):
# viadict      2 non-null uint64
# viacolumn    2 non-null uint64
```
(i.e. both columns are uint64s)

#### Output of ``pd.show_versions()``

<details>
INSTALLED VERSIONS
------------------
commit: None
python: 3.5.2.final.0
python-bits: 64
OS: Windows
OS-release: 7
machine: AMD64
processor: Intel64 Family 6 Model 45 Stepping 7, GenuineIntel
byteorder: little
LC_ALL: None
LANG: None
pandas: 0.18.1
nose: 1.3.7
pip: 9.0.1
setuptools: 27.2.0
Cython: 0.25.1
numpy: 1.11.1
scipy: 0.18.0
statsmodels: 0.6.1
xarray: None
IPython: 5.1.0
sphinx: 1.4.1
patsy: 0.4.1
dateutil: 2.5.3
pytz: 2016.6.1
blosc: None
bottleneck: None
tables: 3.2.2
numexpr: 2.6.1
matplotlib: 1.5.3
openpyxl: None
xlrd: 1.0.0
xlwt: 1.1.2
xlsxwriter: 0.9.2
lxml: None
bs4: 4.5.1
html5lib: None
httplib2: None
apiclient: None
sqlalchemy: 1.0.13
pymysql: None
psycopg2: None
jinja2: 2.8
boto: 2.42.0
pandas_datareader: None
</details>



Discussion:

Yeah, uint64 support is generally spotty.  PR to fix welcome!

xref #14721, xref #4471

Resolving patch:
diff --git a/pandas/core/internals.py b/pandas/core/internals.py
--- a/pandas/core/internals.py
+++ b/pandas/core/internals.py
@@ -4314,11 +4314,6 @@ def form_blocks(arrays, names, axes):
         elif is_datetimetz(v):
             datetime_tz_items.append((i, k, v))
         elif issubclass(v.dtype.type, np.integer):
-            if v.dtype == np.uint64:
-                # HACK #2355 definite overflow
-                if (v > 2**63 - 1).any():
-                    object_items.append((i, k, v))
-                    continue
             int_items.append((i, k, v))
         elif v.dtype == np.bool_:
             bool_items.append((i, k, v))


Test patch:
diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py
--- a/pandas/tests/frame/test_constructors.py
+++ b/pandas/tests/frame/test_constructors.py
@@ -183,13 +183,14 @@ def test_constructor_bool(self):
         self.assertEqual(df.values.dtype, np.bool_)
 
     def test_constructor_overflow_int64(self):
+        # see gh-14881
         values = np.array([2 ** 64 - i for i in range(1, 10)],
                           dtype=np.uint64)
 
         result = DataFrame({'a': values})
-        self.assertEqual(result['a'].dtype, object)
+        self.assertEqual(result['a'].dtype, np.uint64)
 
-        # #2355
+        # see gh-2355
         data_scores = [(6311132704823138710, 273), (2685045978526272070, 23),
                        (8921811264899370420, 45),
                        (long(17019687244989530680), 270),
@@ -198,7 +199,7 @@ def test_constructor_overflow_int64(self):
         data = np.zeros((len(data_scores),), dtype=dtype)
         data[:] = data_scores
         df_crawls = DataFrame(data)
-        self.assertEqual(df_crawls['uid'].dtype, object)
+        self.assertEqual(df_crawls['uid'].dtype, np.uint64)
 
     def test_constructor_ordereddict(self):
         import random
diff --git a/pandas/tests/frame/test_operators.py b/pandas/tests/frame/test_operators.py
--- a/pandas/tests/frame/test_operators.py
+++ b/pandas/tests/frame/test_operators.py
@@ -378,10 +378,10 @@ def test_arith_flex_frame(self):
                     result = getattr(self.mixed_int, op)(2 + self.mixed_int)
                     exp = f(self.mixed_int, 2 + self.mixed_int)
 
-                    # overflow in the uint
+                    # no overflow in the uint
                     dtype = None
                     if op in ['sub']:
-                        dtype = dict(B='object', C=None)
+                        dtype = dict(B='uint64', C=None)
                     elif op in ['add', 'mul']:
                         dtype = dict(C=None)
                     assert_frame_equal(result, exp)
@@ -410,10 +410,10 @@ def test_arith_flex_frame(self):
                             2 + self.mixed_int)
                         exp = f(self.mixed_int, 2 + self.mixed_int)
 
-                        # overflow in the uint
+                        # no overflow in the uint
                         dtype = None
                         if op in ['sub']:
-                            dtype = dict(B='object', C=None)
+                            dtype = dict(B='uint64', C=None)
                         elif op in ['add', 'mul']:
                             dtype = dict(C=None)
                         assert_frame_equal(result, exp)