2012-09-10 163 views
4

我有一个熊猫数据帧“DT = MYFUNC()”,并从IDLE输出的屏幕拷贝如下:为什么熊猫在一种情况下会导致“ZeroDivisionError”,但在另一种情况下却不会呢?

>>> 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 
>>> 

它花费了我很多时间去弄明白为什么熊猫引发“ZeroDivisionError:浮法事业部',而熊猫都非常好,下面的示例代码:

tuples = [('000719','20100331'),('000719','20100930'),('002164','20080331')] 
index = MultiIndex.from_tuples(tuples, names=['STK_ID', 'RPT_Date']) 
dt =DataFrame({'tax':[0,0,0],'ebt':[0,0,0]},index=index) 
dt['tax_rate'] = dt.tax/dt.ebt 

>>> dt 
       ebt tax tax_rate 
STK_ID RPT_Date      
000719 20100331 0 0  NaN 
     20100930 0 0  NaN 
002164 20080331 0 0  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 
+0

你可以检查第一个例子的dt.dtypes吗?我也无法重现这种行为。 –

+0

'dt.dtypes'显示'税'和'ebt'是'对象'(我不知道为什么)。我能收到你的电子邮件吗?我可以将您的整个源代码和SQLite数据文件发送给您,然后您可以重现该场景。通常,程序从SQLite后端获取财务报告数据,并尝试计算财务比率... – bigbug

回答

2

@bigbug,你是如何获取数据了SQLite的后端?如果你看看pandas.io.sqlread_frame方法有一个coerce_float参数,如果可能的话,应该将数字数据转换为浮点数。

你的第二个例子工作,因为DataFrame的构造函数试图聪明的类型。如果您将dtype设置为对象,那么它将失败:

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) 

请再次检查您的数据导入代码,并让我知道您找到了什么?

+0

'df = psql.frame_query(sqlstr,con = cx,coerce_float = True)'是获取数据的代码来自SQLite。我认为'psql.frame_query'效果很好,它为具有数据的SQLite列创建'float64',将'object'列分配给SQLite列为空(NULL)。 (大熊猫也可以默认分配'float64'吗?)。我一步步跟踪内部逻辑流程,发现'DataFrame.diff()'是原因,它将数据类型从'float64'更改为'object'! – bigbug

+0

我附上问题区域中的相关代码和输出。请看看。 'diff()'在碰到边界时会改变数据类型吗? – bigbug

+0

啊,这是一个混合dtype DataFrame的错误。我在这里提交了一个错误报告。作为解决方案,如果您将折扣列转换为浮动,那么它应该可以工作(请参阅https://github.com/pydata/pandas/issues/1896) –

0

我没有安倍重现该行为(I尝试创建DataFrames从整数,浮动和numpy阵列),购买我认为这是一个更好的主意,以NaNtax_rate列和然后覆盖的值时,ebt是非零:

dt['tax_rate'] = numpy.nan 
dt['tax_rate'][dt.ebt != 0] = dt.tax[dt.ebt != 0]/dt.ebt[dt.ebt != 0] 
相关问题