title: Safely downcast a float to the smallest possible integer type
body: <p>Pandas and numpy have a variety of ways to change numerical types but I couldn't find an automated way to safely convert a float to the smallest possible integer, given that no numerical info can be lost.</p>
  
  <p>For example:</p>
  
  <pre><code>1.0 (float32)  -&gt;  1 (int32)   # OK, 1 == 1.0
  1.0 (float32)  -&gt;  1 (int8)    # also OK, just more compact storage
  1.4 (float32)  -&gt;  1 (int8)    # not OK, 1 != 1.1
  </code></pre>
  
  <p>Here's some sample data:</p>
  
  <pre><code>df=pd.DataFrame({ 'i':[1.,333,555_666_777_888],
                    'j':[1.,333,555_666],
                    'x':np.random.randn(3) })
  </code></pre>
  
  <p>Looks like this (dtypes are all float64):</p>
  
  <pre><code>              i         j         x
  0  1.000000e+00       1.0  0.852965
  1  3.330000e+02     333.0 -0.955869
  2  5.556668e+11  555666.0 -0.023493
  </code></pre>
  
  <p>Desired conversion</p>
  
  <pre><code>              i       j         x
  0             1       1 -2.304234
  1           333     333 -0.652469
  2  555666777888  555666 -1.218302
  </code></pre>
  
  <p>with dtypes:</p>
  
  <pre><code>i      int64
  j      int32
  x    float64
  </code></pre>
  
  <p>I have a simple approach that I'll offer as an answer, but perhaps there are better ways or perhaps this is already part of pandas or numpy and I wasn't aware of it.</p>
  
  <p>Also I'm punting on missing values in the answer (NaNs) as I don't have the latest version of of pandas (24.x) which allows integers to be NaN, so maybe someone would like to address that in an answer.</p>
  
  <p>Note that there are few ways to convert floats to ints mentioned in this question:  <a href="https://stackoverflow.com/questions/21291259/convert-floats-to-ints-in-pandas/55753621#55753621">Convert floats to ints in Pandas?</a>, but none of them addresses the potential loss of numerical precision in converting something like 2.1 to 2.</p>