web-dev-qa-db-ja.com

Pandas Excelwriter?を使用してStringIOオブジェクトに書き込みます。

StringIOオブジェクトをpd.to_csv()に問題なく渡すことができます。

_io = StringIO.StringIO()
pd.DataFrame().to_csv(io)
_

しかし、Excelライターを使用すると、さらに多くの問題が発生します。

_io = StringIO.StringIO()
writer = pd.ExcelWriter(io)
pd.DataFrame().to_Excel(writer,"sheet name")
writer.save()   
_

を返します

_AttributeError: StringIO instance has no attribute 'rfind'
_

pd.ExcelWriter()を呼び出さずにExcelWriterオブジェクトを作成しようとしていますが、問題が発生しています。これは私がこれまでに試したことです:

_from xlsxwriter.workbook import Workbook
writer = Workbook(io)
pd.DataFrame().to_Excel(writer,"sheet name")
writer.save()
_

しかし今、私は_AttributeError: 'Workbook' object has no attribute 'write_cells'_を取得しています

pandasデータフレームをExcel形式でStringIOオブジェクトに保存するにはどうすればよいですか?

12
A User

Pandasは、各ライターエンジンがStringIOをサポートしていますが、ExcelWriterコンストラクターへのファイル名パスを想定しています。おそらく、それはパンダのバグ/機能リクエストとして提起されるべきです。

それまでの間、Pandas xlsxwriterエンジンを使用した回避策の例を次に示します。

import pandas as pd
import StringIO

io = StringIO.StringIO()

# Use a temp filename to keep pandas happy.
writer = pd.ExcelWriter('temp.xlsx', engine='xlsxwriter')

# Set the filename/file handle in the xlsxwriter.workbook object.
writer.book.filename = io

# Write the data frame to the StringIO object.
pd.DataFrame().to_Excel(writer, sheet_name='Sheet1')
writer.save()
xlsx_data = io.getvalue()

Update:Pandas 0.17現在、これをより直接的に行うことが可能です:

# Note, Python 2 example. For Python 3 use: output = io.BytesIO().
output = StringIO.StringIO()

# Use the StringIO object as the filehandle.
writer = pd.ExcelWriter(output, engine='xlsxwriter')

XlsxWriterドキュメントの データフレーム出力を文字列に保存する も参照してください。

30
jmcnamara

Pandas.io.Excelのソースを一瞥すると、ライターとしてxlwtを使用してもかまわないのであれば、それほど問題にはならないように見えます。他のエンジンもそれほど難しいことではないかもしれませんが、そのsaveメソッドはストリームまたはファイルパスを使用するため、xlwtは簡単に飛び出します。

pandasを満足させるために、最初にファイル名を渡す必要があります。これは、ファイル名拡張子をエンジンと照合して、サポートされている形式であることを確認するためです。ただし、xlwtエンジンの場合は、ファイル名をオブジェクトのpath属性に詰め込んでから、saveメソッドで使用します。path属性をストリームに変更すると、saveメソッドを呼び出したときにそのストリームに問題なく保存されます。

次に例を示します。

import pandas as pd
import StringIO
import base64

df = pd.DataFrame.from_csv('http://moz.com/top500/domains/csv')
xlwt_writer = pd.io.Excel.get_writer('xlwt')
my_writer = xlwt_writer('whatever.xls')  #make pandas happy 
xl_out = StringIO.StringIO()
my_writer.path = xl_out  
df.to_Excel(my_writer)
my_writer.save()
print base64.b64encode(xl_out.getvalue())

それはそれをするための速くて簡単で少し汚い方法です。ところで...それを行うためのよりクリーンな方法は、ExcelWriter(またはその既存のサブクラスの1つ、たとえば_XlwtWriter)をサブクラス化することです-しかし、正直なところ、パス属性の更新にはほとんど関与していないので、行くよりも簡単な方法を示すことに投票しました少し長いルート。

6
clockwatcher

engine=to_Excelとしてxlsxwriterを使用していない場合は、メモリ内でopenpyxlを使用するための解決策を次に示します。

in_memory_file = StringIO.StringIO()
xlw = pd.ExcelWriter('temp.xlsx', engine='openpyxl')
# ... do many .to_Excel() thingies
xlw.book.save(in_memory_file)
# if you want to read it or stream to a client, don't forget this
in_memory_file.seek(0)

説明:ExcelWriterラッパークラスは、.bookプロパティを介してエンジンの個々のワークブックを公開します。 openpyxlの場合、通常どおりWorkbook.saveメソッドを使用できます。

3
Deano