2014-12-18 18 views
2

我正在熊猫写一些数据分析管道。我一直在使用的数据框中的一列是由自定义编写的类组成的对象,每个类都用一个字符串初始化,从中读取各种具有正则表达式的信息并存储在对象的属性中。子类的结构类似于人们如何实现生命之树(例如,Tiger是猫的一个子类,它是动物的一个子类,并且经常 - 但不总是 - 具有相同超类的动物将共享方法)。它还有一些可用于计算的有用方法。对于海峡再版方法返回用于初始化它,像这样的字符串:制作自定义类xlsxwriter友好

class Animal(object): 

    def __init__(self, name): 
     self.name = name 
     self.group = self.__class__.__name__ 

    def __repr__(self): 
     return self.name.__repr__() 

    def __str__(self): 
     return self.name.__str__() 

我使用这段代码写入数据帧到Excel电子表格的字典:

 with pd.ExcelWriter(saveas) as writer: 
      for key, val in dictionary.items(): 
       print key 
       write_index = not val.data_frame.index.is_integer() 
       val.to_excel(writer, sheet_name=key, index=write_index) 
      writer.save() 

这意味着当我想查看我的数据框时,我看到一个字符串。我已经使用上,在他们拥有这些对象的数据帧的to_csv()方法没有问题,但是当我用熊猫数据帧的to_excel()方法中,我得到以下错误:

File "C:\Users\Mike\Anaconda\lib\site-packages\xlsxwriter\worksheet.py", line 406, in write 
    f = float(token) 

TypeError: float() argument must be a string or a number 

所以我在worksheet.py跟踪下来的代码,违规线条看起来是这样的:

try: 
     f = float(token) ##THIS IS WHERE THE CODE FAILS 
     if not self._isnan(f) and not self._isinf(f): 
      return self.write_number(row, col, f, *args[1:]) 
    except ValueError: 
     pass 

    # Finally try string. 
    try: 
     str(token) 
     return self.write_string(row, col, *args) 
    except ValueError: 
     raise TypeError("Unsupported type %s in write()" % type(token)) 

我已经添加到上面的代码中的注释,以显示该失败发生。我的对象没有float方法,所以不是ValueError而是抛出TypeErrors。从上面的代码中可以清楚的看出,如果我们可以通过第二次尝试的话,写作将开始(因为我的课程有一个方法str方法)。所以我给了我的自定义类float方法,该方法返回一个ValueError,以便可以触发except子句。

然而,使用xlsx编写器存在更多的问题,其中一些类似的问题涉及我的类中缺少某些方法(我在每种情况下都添加了这些方法)。然而,这只是延缓问题:

File "C:\Users\Mike\Anaconda\lib\site-packages\xlsxwriter\sharedstrings.py", line 95, in _write_si 
    string = re.sub('(_x[0-9a-fA-F]{4}_)', r'_x005F\1', string) 

现在,这里(我看了一下代码)的问题,一旦串已经写入表,xlsxwriter运行某些功能得到所有字符串来自书面文件。这个问题似乎是,一旦表单被写入了(write.save()的所有内容都会正确传递),xlsxwriter会假定写入的字符串始终是字符串,并将它们视为它,而不是将它们封装在str()函数就像以前一样。

现在,我可以去修改有问题的代码,但我不想处理使用xlsxwriter进行更新的问题。我可以简单地让我的类从str继承,但是这看起来像unpythonic,因为我不想使用几乎任何字符串方法。最后,我可以通过将这个子类中的所有东西都变成一个字符串来清理数据框,但这意味着我必须重写很多我使用的东西,这取决于能够使用DataFrame.to_excel方法。我能在课堂上做些什么,使我不必继承str的所有内容?

+0

,尝试使用'%debug'来查看有问题的'token'是什么。 –

+1

违规令牌是我在帖子中讨论的类中的一员。 – MTrenfield

+0

你确定*这是什么标记,看起来像浮动(令牌)不会提高,如果是这种情况... –

回答

3

最简单的方法可能是,如果你使用IPython的只是实现自己的引擎使用

from pandas import io 
class MyXLSWriter(io.excel.xlsx.writer): 
    def write_cells(self, cells,*args,**kwargs): 
     for cell in cells: 
      if isinstance(cell.val,(MyCustomClass1,MyCustomClassN)): 
       cell.val = str(cell.val) #or some other representaion... 
     io.excel.xlsx.writer.write_cells(self,cells,*args,**kwargs) 

my_df.to_excell(fname,engine=MyXLSWriter) 

我觉得至少......我完全没有测试它...

+0

也许我没有清楚地说出我的问题。我已经这样做了。 – MTrenfield

+0

是的,我看到后... –

+0

啊,好的。没问题。我认为,如果他们让我(这将是我的第一个开源贡献!),我可能会把它带给工作在xlsxwriter上的人,甚至可能自己工作。看起来像这样的东西应该没有错误地通过。 – MTrenfield