2014-12-18 2 views
2

팬더에 데이터 분석 파이프 라인을 쓰고 있습니다. 제가 작업해온 데이터 프레임의 컬럼 중 하나는 문자열로 초기화되는 커스텀 쓰여진 클래스의 객체로 구성되어 있습니다. 여기에서 정규 표현식으로 다양한 정보를 읽고 객체의 속성에 저장합니다. 하위 클래스 구조는 생명 나무를 구현하는 방법과 유사합니다 (예 : Tiger는 Animal의 하위 클래스 인 Cat의 하위 클래스이며 자주는 아니지만 항상 동일한 수퍼 클래스를 가진 동물이 메서드를 공유합니다). 또한 계산에 사용할 수있는 유용한 메소드가 있습니다.맞춤 클래스 만들기 xlsxwriter friendly

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__() 

내가 엑셀 ​​스프레드 시트 데이터 프레임의 사전을 작성하는 코드의이 비트를 사용하고 있습니다 : STR에 repr를 들어 방법은과 같이, 초기화하는 데 사용 된 문자열을 반환 :

 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를 던지고 있습니다. 위의 코드에서 두 번째 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에서 상속받는 클래스를 만들 수는 있지만 문자열 메서드를 거의 사용하지 않으려 고하는 것은 당연한 것 같습니다. 마지막으로이 하위 클래스의 모든 것을 가져 와서 문자열로 되돌려 데이터 프레임을 위생 할 수는 있지만 DataFrame.to_excel을 사용할 수 있는지에 따라 사용하는 많은 것을 다시 작성해야한다는 것을 의미합니다. 방법. 내가 str에서 모든 것을 상속받지 못하게하는 수업 내에서 할 수있는 일이 있습니까?

+0

를 사용하는 자신의 엔진을 구현하는 아마, 악의적 인'token '이 무엇인지보기 위해'% debug'를 사용해보십시오. –

+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