【问题标题】:Error when trying to apply log method to pandas data frame column in Python尝试将日志方法应用于 Python 中的 pandas 数据框列时出错
【发布时间】:2013-06-02 20:03:36
【问题描述】:

所以,我对 Python 和 Pandas(以及一般编程)非常陌生,但是在使用看似简单的函数时遇到了麻烦。因此,我使用通过 SQL 查询提取的数据创建了以下数据框(如果您需要查看 SQL 查询,请告诉我,我会粘贴它)

spydata = pd.DataFrame(row,columns=['date','ticker','close', 'iv1m', 'iv3m'])
tickerlist = unique(spydata[spydata['date'] == '2013-05-31'])

之后,我编写了一个函数,使用其中已有的数据在数据框中创建一些新列:

def demean(arr):
    arr['retlog'] = log(arr['close']/arr['close'].shift(1))

    arr['10dvol'] = sqrt(252)*sqrt(pd.rolling_std(arr['ret'] , 10 ))  
    arr['60dvol'] = sqrt(252)*sqrt(pd.rolling_std(arr['ret'] , 10 ))  
    arr['90dvol'] = sqrt(252)*sqrt(pd.rolling_std(arr['ret'] , 10 ))  
    arr['1060rat'] = arr['10dvol']/arr['60dvol']
    arr['1090rat'] = arr['10dvol']/arr['90dvol']
    arr['60dis'] = (arr['1060rat'] - arr['1060rat'].mean())/arr['1060rat'].std()
    arr['90dis'] = (arr['1090rat'] - arr['1090rat'].mean())/arr['1090rat'].std()
    return arr

我唯一遇到问题的部分是函数的第一行:

arr['retlog'] = log(arr['close']/arr['close'].shift(1))

当我使用这个命令运行时,我得到一个错误:

result = spydata.groupby(['ticker']).apply(demean)

错误:

    ---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-196-4a66225e12ea> in <module>()
----> 1 result = spydata.groupby(['ticker']).apply(demean)
      2 results2 = result[result.date == result.date.max()]
      3 

C:\Python27\lib\site-packages\pandas-0.11.0-py2.7-win32.egg\pandas\core\groupby.pyc in apply(self, func, *args, **kwargs)
    323         func = _intercept_function(func)
    324         f = lambda g: func(g, *args, **kwargs)
--> 325         return self._python_apply_general(f)
    326 
    327     def _python_apply_general(self, f):

C:\Python27\lib\site-packages\pandas-0.11.0-py2.7-win32.egg\pandas\core\groupby.pyc in _python_apply_general(self, f)
    326 
    327     def _python_apply_general(self, f):
--> 328         keys, values, mutated = self.grouper.apply(f, self.obj, self.axis)
    329 
    330         return self._wrap_applied_output(keys, values,

C:\Python27\lib\site-packages\pandas-0.11.0-py2.7-win32.egg\pandas\core\groupby.pyc in apply(self, f, data, axis, keep_internal)
    632             # group might be modified
    633             group_axes = _get_axes(group)
--> 634             res = f(group)
    635             if not _is_indexed_like(res, group_axes):
    636                 mutated = True

C:\Python27\lib\site-packages\pandas-0.11.0-py2.7-win32.egg\pandas\core\groupby.pyc in <lambda>(g)
    322         """
    323         func = _intercept_function(func)
--> 324         f = lambda g: func(g, *args, **kwargs)
    325         return self._python_apply_general(f)
    326 

<ipython-input-195-47b6faa3f43c> in demean(arr)
      1 def demean(arr):
----> 2     arr['retlog'] = log(arr['close']/arr['close'].shift(1))
      3     arr['10dvol'] = sqrt(252)*sqrt(pd.rolling_std(arr['ret'] , 10 ))
      4     arr['60dvol'] = sqrt(252)*sqrt(pd.rolling_std(arr['ret'] , 10 ))
      5     arr['90dvol'] = sqrt(252)*sqrt(pd.rolling_std(arr['ret'] , 10 ))

AttributeError: log

我尝试将函数更改为 np.log 和 math.log,在这种情况下我得到错误

TypeError: only length-1 arrays can be converted to Python scalars

我已尝试查找此内容,但没有找到任何直接适用的内容。有什么线索吗?

【问题讨论】:

    标签: python numpy pandas dataframe


    【解决方案1】:

    当列的数据类型不是数字时会发生这种情况。试试

    arr['retlog'] = log(arr['close'].astype('float64')/arr['close'].astype('float64').shift(1))
    

    我怀疑这些数字存储为通用“对象”类型,我知道这会导致日志抛出该错误。这是问题的简单说明:

    In [15]: np.log(Series([1,2,3,4], dtype='object'))
    ---------------------------------------------------------------------------
    AttributeError                            Traceback (most recent call last)
    <ipython-input-15-25deca6462b7> in <module>()
    ----> 1 np.log(Series([1,2,3,4], dtype='object'))
    
    AttributeError: log
    
    In [16]: np.log(Series([1,2,3,4], dtype='float64'))
    Out[16]: 
    0    0.000000
    1    0.693147
    2    1.098612
    3    1.386294
    dtype: float64
    

    您对math.log 的尝试无效,因为该函数仅适用于单个数字(标量),而不是列表或数组。

    对于它的价值,我认为这是一个令人困惑的错误消息;无论如何,它曾经让我难过一段时间。我想知道它是否可以改进。

    【讨论】:

    • 这很有效,你的解释完全有道理。谢谢!
    • @Dan 你为什么不打开一个问题看看是否存在可以捕获/改进此错误的情况
    • @Jeff 看起来像是四年前我们在 numpy 上发布的...github.com/numpy/numpy/issues/1611 (!)
    • 当我从包含 float 和 None 值的混合列表创建列时,我经常遇到这种情况。只要至少有一个数字,s = pd.Series([... values ...]) 就有一个数字类型,所以像np.log(s) 这样的东西可以工作,但s = pd.Series([None, None, ...]) 有对象类型,np.log(s) 会失败。我最近的一个例子归结为:s = pd.Series([None, None]); np.log(s.where(s, 1)) 失败,AttributeError: 'int' object has no attribute 'log':即使s.where(s, 1) 是一列 1,它维护 dtype Object :(
    猜你喜欢
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多