Logarithm of a pandas series/dataframe
<p>In short: How can I get a logarithm of a column of a pandas dataframe?
I thought <code>numpy.log()</code> should work on it, but it isn't. I suspect it's because I have some <code>NaN</code>s in the dataframe?</p>

<p>My whole code is below. It may seem a bit chaotic, basically my ultimate goal (a little exaggerated) is to plot different rows of different selected columns in several selected columns into several subplots (hence the three embedded for loops iterating between different groups... if you suggest a more elegant solution, I will appreciate it but it is not the main thing that's pressing me). I need to plot a logarithm of some values from one dataframe + 1 versus some values of the other dataframe. And here is the problem, on the plotting line with np.log I get this error: <code>AttributeError: 'float' object has no attribute 'log'</code> (and if I use math instead of np, I get this: <code>TypeError: cannot convert the series to &lt;type 'float'&gt;</code>)
What may I do about it?</p>

<p>Thank you.
Here is the code:</p>

<pre><code>import numpy as np
import math
import pandas as pd
import matplotlib.pyplot as plt

hf = pd.DataFrame({'Z':np.arange(0,100,1),'A':(10*np.random.rand(100)), 'B':(10*np.random.rand(100)),'C':(10*np.random.rand(100)),'D':(10*np.random.rand(100)),'E':(10*np.random.rand(100)),'F':(10*np.random.rand(100))})
df = pd.DataFrame({'Z':np.arange(0,100,1),'A':(10*np.random.rand(100)), 'B':(10*np.random.rand(100)),'C':(10*np.random.rand(100)),'D':(10*np.random.rand(100)),'E':(10*np.random.rand(100)),'F':(10*np.random.rand(100))})
hf.loc[0:5,'A']=np.nan
df.loc[0:5,'A']=np.nan
hf.loc[53:58,'B']=np.nan
df.loc[53:58,'B']=np.nan
hf.loc[90:,'C']=np.nan
df.loc[90:,'C']=np.nan
I = ['A','B']
II = ['C','D']
III = ['E','F']
IV = ['F','A']
runs = [I,II,III,IV]
inds = [10,20,30,40]

fig = plt.figure(figsize=(6,4))
for r in runs:
    data = pd.DataFrame(index=df.index,columns=r)
    HF = pd.DataFrame(index=hf.index,columns=r)
    #pdb.set_trace()
    for i in r:
        data.loc[:,i] = df.loc[:,i]
        HF.loc[:,i] = hf.loc[:,i]
        for c,z in enumerate(inds):
            ax=fig.add_subplot()
            ax = plt.plot(math.log1p(HF.loc[z]),Tdata.loc[z],linestyle=":",marker="o",markersize=5,label=inds[c].__str__())
# or the other version
#plt.plot(np.log(1 + HF.loc[z]),Tdata.loc[z],linestyle=":",marker="o",markersize=5,label=inds[c].__str__())
</code></pre>

<p>As @Jason pointed out, <a href="http://stackoverflow.com/a/16968491/5553319">this answer</a> did the trick! Thank you!</p>

<p>The problem isn't that you have <code>NaN</code> values, it's that you <em>don't</em> have <code>NaN</code> values, you have <strong>strings</strong> <code>"NaN"</code> which the <code>ufunc</code> np.log doesn't know how to deal with. Replace the beginning of your code with:</p>

<pre><code>hf = pd.DataFrame({'Z':np.arange(0,100,1),'A':(10*np.random.rand(100)), 'B':(10*np.random.rand(100)),'C':(10*np.random.rand(100)),'D':(10*np.random.rand(100)),'E':(10*np.random.rand(100)),'F':(10*np.random.rand(100))})
df = pd.DataFrame({'Z':np.arange(0,100,1),'A':(10*np.random.rand(100)), 'B':(10*np.random.rand(100)),'C':(10*np.random.rand(100)),'D':(10*np.random.rand(100)),'E':(10*np.random.rand(100)),'F':(10*np.random.rand(100))})
hf.loc[0:5,'A'] = np.nan
df.loc[0:5,'A'] = np.nan
hf.loc[53:58,'B'] = np.nan
df.loc[53:58,'B'] = np.nan
hf.loc[90:,'C'] = np.nan
df.loc[90:,'C'] = np.nan
</code></pre>

<p>And everything should work nicely with <code>np.log</code></p>

python pandas numpy matplotlib