<h3 dir="auto">Reproducing code example:</h3>

<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import numpy as np

integer_list = [18446744073709551615]
arr = np.array(integer_list)
arr.dtype

# Returns: dtype('uint64')

# So far, so good... But:

# Same list as above, with with a smaller number at the first index
integer_list = [
    9223372036854775807,
    18446744073709551615
]
arr = np.array(integer_list)
arr.dtype
# Returns: dtype('float64')"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">numpy</span> <span class="pl-k">as</span> <span class="pl-s1">np</span>

<span class="pl-s1">integer_list</span> <span class="pl-c1">=</span> [<span class="pl-c1">18446744073709551615</span>]
<span class="pl-s1">arr</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">array</span>(<span class="pl-s1">integer_list</span>)
<span class="pl-s1">arr</span>.<span class="pl-s1">dtype</span>

<span class="pl-c"># Returns: dtype('uint64')</span>

<span class="pl-c"># So far, so good... But:</span>

<span class="pl-c"># Same list as above, with with a smaller number at the first index</span>
<span class="pl-s1">integer_list</span> <span class="pl-c1">=</span> [
    <span class="pl-c1">9223372036854775807</span>,
    <span class="pl-c1">18446744073709551615</span>
]
<span class="pl-s1">arr</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">array</span>(<span class="pl-s1">integer_list</span>)
<span class="pl-s1">arr</span>.<span class="pl-s1">dtype</span>
<span class="pl-c"># Returns: dtype('float64')</span></pre></div>
<p dir="auto">It looks like Numpy only looks at the first element in the object when deciding what dtype the array should have. I think (although I'm not sure) that this behaviour causes unpredictable behaviour in Pandas down the line.</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import pandas as pd

integer_list = [
    9223372036854775807,
    18446744073709551615
]

df = pd.DataFrame(integer_list)
df[0].dtype
# Returns: dtype('uint64')

df[0].to_numpy(int)
# Returns (on Windows*): array([-1, -1])
# Returns (on Debian): array([9223372036854775807, -1])"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">pandas</span> <span class="pl-k">as</span> <span class="pl-s1">pd</span>

<span class="pl-s1">integer_list</span> <span class="pl-c1">=</span> [
    <span class="pl-c1">9223372036854775807</span>,
    <span class="pl-c1">18446744073709551615</span>
]

<span class="pl-s1">df</span> <span class="pl-c1">=</span> <span class="pl-s1">pd</span>.<span class="pl-v">DataFrame</span>(<span class="pl-s1">integer_list</span>)
<span class="pl-s1">df</span>[<span class="pl-c1">0</span>].<span class="pl-s1">dtype</span>
<span class="pl-c"># Returns: dtype('uint64')</span>

<span class="pl-s1">df</span>[<span class="pl-c1">0</span>].<span class="pl-en">to_numpy</span>(<span class="pl-s1">int</span>)
<span class="pl-c"># Returns (on Windows*): array([-1, -1])</span>
<span class="pl-c"># Returns (on Debian): array([9223372036854775807, -1])</span></pre></div>
<p dir="auto">When using <code class="notranslate">to_numpy()</code>, Pandas calls <code class="notranslate">np.asarray()</code> under the hood and passes the values of the Series. So I don't think anything is wrong on the Pandas side. Numpy seems to get confused and makes some wrong decisions about the appropriate length and signedness of the integer it should use.</p>
<h3 dir="auto">NumPy/Python version information:</h3>
<p dir="auto"><strong>Windows</strong><br>
Numpy version: 1.19.2<br>
Python version: 3.8.8 (default, Feb 24 2021, 15:54:32) [MSC v.1928 64 bit (AMD64)]</p>
<p dir="auto"><strong>Debian</strong><br>
Numpy version: 1.20.2 3.7.3<br>
Python version: Python 3.7.3 (default, Jan 22 2021, 20:04:44)  [GCC 8.3.0]</p>
<p dir="auto">And, to maybe save someone some time:</p>
<p dir="auto">On Windows, a c_long object is always 32 bit, regardless of the OS being 64 bit (as opposed to Unix). See: <a href="https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types" rel="nofollow">https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types</a></p>
<p dir="auto">When <code class="notranslate">np.array()</code> or <code class="notranslate">.asarray()</code> is used to go from a list of integers, without specifying a dtype explicitly, it can pick default dtypes including int64 &amp; uint64. But there's a strange corner case where it defaults to float64 and loses precision, even though all the values could be uint64. Specfically, this occurs when some but not all values can be int64:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="In [11]: max_int64 = np.iinfo(np.int64).max                                                                            

In [12]: np.array([max_int64]).dtype                                                                                   
Out[12]: dtype('int64')

In [13]: np.array([max_int64 + 1]).dtype                                                                               
Out[13]: dtype('uint64')

In [14]: np.array([max_int64 + 1, max_int64]).dtype                                                                    
Out[14]: dtype('float64')"><pre class="notranslate"><span class="pl-v">In</span> [<span class="pl-c1">11</span>]: <span class="pl-s1">max_int64</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">iinfo</span>(<span class="pl-s1">np</span>.<span class="pl-s1">int64</span>).<span class="pl-s1">max</span>                                                                            

<span class="pl-v">In</span> [<span class="pl-c1">12</span>]: <span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-s1">max_int64</span>]).<span class="pl-s1">dtype</span>                                                                                   
<span class="pl-v">Out</span>[<span class="pl-c1">12</span>]: <span class="pl-en">dtype</span>(<span class="pl-s">'int64'</span>)

<span class="pl-v">In</span> [<span class="pl-c1">13</span>]: <span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-s1">max_int64</span> <span class="pl-c1">+</span> <span class="pl-c1">1</span>]).<span class="pl-s1">dtype</span>                                                                               
<span class="pl-v">Out</span>[<span class="pl-c1">13</span>]: <span class="pl-en">dtype</span>(<span class="pl-s">'uint64'</span>)

<span class="pl-v">In</span> [<span class="pl-c1">14</span>]: <span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-s1">max_int64</span> <span class="pl-c1">+</span> <span class="pl-c1">1</span>, <span class="pl-s1">max_int64</span>]).<span class="pl-s1">dtype</span>                                                                    
<span class="pl-v">Out</span>[<span class="pl-c1">14</span>]: <span class="pl-en">dtype</span>(<span class="pl-s">'float64'</span>)</pre></div>
<p dir="auto">It doesn't depend on the order they're in, and it's not a general consequence of having two values rather than one - two values above this threshold get <code class="notranslate">uint64</code> as I'd expect.</p>
<p dir="auto">Tested on Numpy 1.18.4, Python 3.8.2.</p>
<p dir="auto">Sorry if this has already been discussed; it's a tricky thing to search for. This relates to an issue reported on h5py: <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="619100596" data-permission-text="Title is private" data-url="https://github.com/h5py/h5py/issues/1547" data-hovercard-type="issue" data-hovercard-url="/h5py/h5py/issues/1547/hovercard" href="https://github.com/h5py/h5py/issues/1547">h5py/h5py#1547</a> .</p>