Convert sparse pandas dataframe with `NaN` into integer values
<p>I have a binary pandas dataframe with values <code>0.0</code>, <code>1.0</code>, and <code>NaN</code>. </p>

<pre><code>import pandas as pd
df = pd.read_csv("file.csv")
</code></pre>

<p>I would like to turn the floats <code>1.0</code> and <code>0.0</code> into integers <code>1</code> and <code>0</code>. Unfortunately, because of <code>NaN</code> value, this command fails:</p>

<pre><code>df.applymap(int)
</code></pre>

<p>The error is:</p>

<pre><code>ValueError: ('cannot convert float NaN to integer', 'occurred at index 0')
</code></pre>

<p>Are there "pandas" alternatives? </p>

<p><strong>UPDATE:</strong></p>

<p>if you need nice looking <strong>string</strong> values you can do it:</p>

<pre><code>In [84]: df.astype(object)
Out[84]:
   a  b    c
0  0  1    0
1  0  0    1
2  1  1    1
3  0  1    1
4  1  1  NaN
</code></pre>

<p>but all values - are strings (<code>object</code> in pandas terms):</p>

<pre><code>In [85]: df.astype(object).dtypes
Out[85]:
a    object
b    object
c    object
dtype: object
</code></pre>

<p>Timings against 500K rows DF:</p>

<pre><code>In [86]: df = pd.concat([df] * 10**5, ignore_index=True)

In [87]: df.shape
Out[87]: (500000, 3)

In [88]: %timeit df.astype(object)
10 loops, best of 3: 113 ms per loop

In [89]: %timeit df.applymap(lambda x: int(x) if pd.notnull(x) else x).astype(object)
1 loop, best of 3: 7.86 s per loop
</code></pre>

<p><strong>OLD answer:</strong></p>

<p>AFAIK you can't do it using modern pandas versions. </p>

<p>Here is a demo:</p>

<pre><code>In [52]: df
Out[52]:
     a    b    c
0  1.0  NaN  0.0
1  NaN  1.0  1.0
2  0.0  0.0  NaN

In [53]: df[pd.isnull(df)] = -1

In [54]: df
Out[54]:
     a    b    c
0  1.0 -1.0  0.0
1 -1.0  1.0  1.0
2  0.0  0.0 -1.0

In [55]: df = df.astype(int)

In [56]: df
Out[56]:
   a  b  c
0  1 -1  0
1 -1  1  1
2  0  0 -1
</code></pre>

<p>we are almost there, let's replace <code>-1</code> with <code>NaN</code>:</p>

<pre><code>In [57]: df[df &lt; 0] = np.nan

In [58]: df
Out[58]:
     a    b    c
0  1.0  NaN  0.0
1  NaN  1.0  1.0
2  0.0  0.0  NaN
</code></pre>

<p>Another demo:</p>

<pre><code>In [60]: df = pd.DataFrame(np.random.choice([0,1], (5,3)), columns=list('abc'))

In [61]: df
Out[61]:
   a  b  c
0  1  0  0
1  1  0  1
2  0  1  1
3  0  0  1
4  0  0  1
</code></pre>

<p>look what happens with <code>c</code> column if we change a single cell in it to <code>NaN</code>:</p>

<pre><code>In [62]: df.ix[4, 'c'] = np.nan

In [63]: df
Out[63]:
   a  b    c
0  1  0  0.0
1  1  0  1.0
2  0  1  1.0
3  0  0  1.0
4  0  0  NaN
</code></pre>

python pandas binary int