使用Python有效地将SPSS数据写入Excel

时间:2016-10-19 07:50:46

标签: python excel spss openpyxl

我正在尝试使用Python将数据从开放的SPSS数据集写入excel文件。以下程序运行正常,但对于具有140万个数据点(2500个案例,700个变量)的文件,大约需要35秒。

现在,我循环遍历每个案例(作为元组),然后将元组的每个元素分配到一个单元格中。 openpyxl是首选的Excel模块(因为我过去没有使用任何其他模块)。

我将把Python程序用于更大的数据集,所以我想知道是否有更有效的逻辑来做到这一点。

BEGIN PROGRAM.

import spssdata
import spss,spssaux, sys
import openpyxl
from openpyxl import Workbook
import gc

#initialise timer
time_start = time.time()

#Create the workbook to save the codebook 
wb=openpyxl.Workbook()
ws1=wb.create_sheet()

spss.StartDataStep()
MyFile = spss.Dataset()
varDict = spssaux.VariableDict()
MyCases=MyFile.cases
MyVars=MyFile.varlist

for varnum, varname in enumerate(MyFile.varlist):
        ws1.cell(row=1,column=varnum+1).value=varname.name
        ws2.cell(row=1,column=varnum+1).value=varname.name

for eachcase in range (len(MyCases)):
    for eachvar in range (len(MyCases[eachcase])):
        ValueToWrite=MyCases[eachcase][eachvar]
        ws1.cell(row=eachcase+2,column=eachvar+1).value=ValueToWrite

spss.EndDataStep()

wb.save("some filename")
del wb
gc.collect()
time_end = time.time()
time_taken = int(time_end-time_start)
print ("Saving took " + str(time_taken) + " seconds.")
END PROGRAM.

3 个答案:

答案 0 :(得分:1)

您可以尝试使用win32com方法。这通常很慢,但它确实具有能够在单个调用中完成大部分数据传输的优点。您只需要将数据准备到适当大小的列表中:

import win32com.client as win32

data = [["A", "B"] for _ in range(10000)]

excel = win32.gencache.EnsureDispatch('Excel.Application')
excel.DisplayAlerts = False
wb = excel.Workbooks.Add()
ws = wb.Worksheets.Add()
ws.Range(ws.Cells(1, 1), ws.Cells(len(data), 2)).Value = data
wb.SaveAs(r'c:\python\test.xlsx')
excel.Application.Quit()

使用range(1000000)计时约需7.5秒。

AFAIK openpyxl无法一次写入多个单元格。

根据您现有的代码,我建议采用以下方式:

import win32com.client as win32
import time
import spss,spssaux, sys

#initialise timer
time_start = time.time()

spss.StartDataStep()
MyFile = spss.Dataset()
MyCases = MyFile.cases
spss.EndDataStep()

excel = win32.gencache.EnsureDispatch('Excel.Application')
excel.DisplayAlerts = False

wb = excel.Workbooks.Add()
ws1 = wb.Worksheets("Sheet1")
ws2 = wb.Worksheets("Sheet2")

# Add header to both sheets
ws1.Range(ws1.Cells(1, 1), ws1.Cells(1, len(MyFile.varlist))).Value = MyFile.varlist
ws2.Range(ws2.Cells(1, 1), ws2.Cells(1, len(MyFile.varlist))).Value = MyFile.varlist

# Copy data
ws1.Range(ws1.Cells(2, 1), ws1.Cells(1 + len(MyCases), len(MyCases[0]))).Value = MyCases

wb.SaveAs(r'e:\python temp\test.xlsx')
excel.Application.Quit()  

print("Saving took {:.1f} seconds.".format(time.time() - time_start))

答案 1 :(得分:0)

确保安装lxml并使用openpyxl的只写模式,假设您可以逐行工作。如果这不是直接可能的话,那么你需要某种可以为你提供行的中间结构。

答案 2 :(得分:0)

In general, the spss.Cursor class (or spssdata.Spssdata) is much faster than the spss.Dataset class, and for this application you do not need the additional features of the Dataset class. While the speed of Dataset is mainly an issue when writing to Statistics, the Cursor class will still probably be faster.