使自定义类xlsxwriter友好

时间:2014-12-18 22:04:07

标签: python oop pandas xlsxwriter

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

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()方法没有任何问题,但是当我使用pandas数据框的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

所以我将它跟踪到workheet.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。从上面的代码中可以清楚地看到,如果我们可以通过第二个try语句来开始写作(因为我的类有一个 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就会运行一些函数来获取写入文件中的所有字符串。问题似乎是一旦表单被写入(所有内容都是在没有错误的情况下传递到writer.save()),xlsxwriter假定写入的字符串一直是字符串,并将它们视为它,而不是将它们包含在str()函数就像以前一样。

现在,我可以去修改有问题的代码,但是我不想通过更新xlsxwriter来处理这个问题。我可以简单地让我的类继承自str,但这似乎是unpythonic,因为我并不想使用几乎任何字符串方法。最后,我可以通过将此子类中的所有内容转换回字符串来清理我的数据框,但这意味着我必须重写我使用的许多依赖于能够使用的东西DataFrame.to_excel方法。在课堂上我能做些什么来节省我从str继承的所有东西?

1 个答案:

答案 0 :(得分:4)

最简单的方法可能是实现自己的引擎使用

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)

我认为至少......我完全没有测试过它......