Python 为什么熊猫会引起';零分错误';在一种情况下,而不是在另一种情况下?

Python 为什么熊猫会引起';零分错误';在一种情况下,而不是在另一种情况下?,python,pandas,Python,Pandas,我有一个数据帧“dt=myfunc()”,并从IDLE复制屏幕输出,如下所示: >>> from __future__ import division >>> dt = __get_stk_data__(['*'], frq='CQQ', from_db=False) # my function >>> dt = dt[dt['ebt']==0][['tax','ebt']] >>> type(dt) <class '

我有一个数据帧“dt=myfunc()”,并从IDLE复制屏幕输出,如下所示:

>>> from __future__ import division
>>> dt = __get_stk_data__(['*'], frq='CQQ', from_db=False) # my function
>>> dt = dt[dt['ebt']==0][['tax','ebt']]
>>> type(dt)
<class 'pandas.core.frame.DataFrame'>
>>> dt
                tax ebt
STK_ID RPT_Date        
000719 20100331   0   0
       20100630   0   0
       20100930   0   0
       20110331   0   0
002164 20080331   0   0
300155 20120331   0   0
600094 20090331   0   0
       20090630   0   0
       20090930   0   0
600180 20090331   0   0
600757 20110331   0   0
>>> dt['tax_rate'] = dt.tax/dt.ebt
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "D:\Python\Lib\site-packages\pandas\core\series.py", line 72, in wrapper
    return Series(na_op(self.values, other.values),
  File "D:\Python\Lib\site-packages\pandas\core\series.py", line 53, in na_op
    result = op(x, y)
ZeroDivisionError: float division
>>> 
我希望熊猫在这两种情况下都提供“NaN”,为什么第一种情况下会出现“ZeroDivisionError”?如何修复它


下面的代码和屏幕输出被附加以提供调试的进一步信息

def __by_Q__(df):
    ''' this function transforms the input financial report data (which
        is accumulative) to qurterly data
    '''
    df_q1=df[df.index.map(lambda x: x[1].endswith("0331"))]

    print 'before diff:\n'
    print df.dtypes
    df_delta = df.diff()
    print '\nafter diff: \n'
    print df_delta.dtypes


    q1_mask = df_delta.index.map(lambda x: x[1].endswith("0331"));
    df_q234 = df_delta[~q1_mask]

    rst = concat([df_q1,df_q234])

    rst=rst.sort_index()
    return rst
屏幕输出:

before diff:

sales                      float64
discount                    object
net_sales                  float64
cogs                       float64
ebt                        float64
tax                        float64

after diff: 

sales                      object
discount                   object
net_sales                  object
cogs                       object
ebt                        object
tax                        object

我没有复制这种行为(我尝试从整数、浮点和numpy数组创建数据帧),我认为将
NaN
分配到
tax\u rate
列,然后在
ebt
非零时覆盖值是一个更好的主意:

dt['tax_rate'] = numpy.nan
dt['tax_rate'][dt.ebt != 0] = dt.tax[dt.ebt != 0] / dt.ebt[dt.ebt != 0]

@bigbug,您是如何从SQLite后端获取数据的?如果查看
pandas.io.sql
read\u frame
方法有一个
强制浮点
参数,如果可能,该参数应将数字数据转换为浮点

第二个示例之所以有效,是因为DataFrame构造函数试图巧妙地处理类型。如果将数据类型设置为object,则会失败:

In [16]: dt = DataFrame({'tax':[0,0,0], 'ebt':[0,0,0]},index=index,dtype=object)

In [17]: dt.tax/dt.ebt
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)

再次检查数据导入代码,并告诉我您发现了什么?

您能检查第一个示例中的dt.dtypes吗?我也不能重现这种行为。'dt.dtypes'显示'tax','ebt'是'object'(我不知道为什么)。能给我你的电子邮件吗?我可以向您发送整个源代码和SQLite数据文件,然后您可以复制该场景。通常,程序从SQLite后端获取财务报告数据,并尝试计算财务比率…“df=psql.frame_query(sqlstr,con=cx,con=curve_float=True)”是从SQLite获取数据的代码。我认为'psql.frame_query'工作得很好,它为包含数据的SQLite列创建'float64',为空(NULL)的SQLite列分配'object'列。(熊猫也可以将“float64”作为默认值分配给它吗?)。我一步一步地跟踪内部逻辑流,发现“DataFrame.diff()”是原因,它将数据类型从“float64”更改为“object”!我将相关代码和输出附加到问题区域。请看一看。“diff()”是否会在到达边界时更改数据类型?啊,这是混合数据类型DataFrame的一个错误。我在这里提交了一份bug报告。作为一种解决方法,如果您将折扣列转换为浮动,那么它应该会起作用(请参阅)您是否可以给出“将折扣列转换为浮动”的示例代码?
In [16]: dt = DataFrame({'tax':[0,0,0], 'ebt':[0,0,0]},index=index,dtype=object)

In [17]: dt.tax/dt.ebt
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)