4

我正在尝试使用 win32 将 pandas 数据框导出到 excel 中。

导出似乎仅在数据框不包含 numpy 数据类型时才有效。

如何将 numpy 数据类型转换为它们的 COM 变体?

这是一个可重现的例子:

 import pandas as pd
 from win32com.client import Dispatch

 # Prepare data

 # data without numpy data type
 xdata1 = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
     'year' : [2000, 2001, 2002, 2002, 2001],
     'pop'  : [1.5, 1.7, 3.6, 2.4, 2.9 ]}
data1 = pd.DataFrame(xdata1, columns = ['year', 'state', 'pop'])
xT1 = [tuple(x) for x in data1.values]# # data to tuples

# data with numpy type
data2 = pd.crosstab(data1.state, data1.year)
xT2 = [tuple(x) for x in data2.values]  # data to tuples

# export the data 
 from win32com.client import Dispatch
 xlApp = Dispatch("Excel.Application")
 xlApp.Visible = 1
 xlApp.Workbooks.Add()
 xlSheet = xlApp.ActiveWorkbook.ActiveSheet

 # write to excel
  xlSheet.Cells(1,1).Value = 'Python Rules!'   # THIS WORKS AS EXPECTED

 # Write to a range : data without numpy data type
  FirstRow = 2
  FirstCol = 3
  LastRow = FirstRow + len(xT1) - 1 # Number of records
  LastCol =  FirstCol + len(xT1[0]) - 1        # Number of columns
   xlSheet.Range(xlSheet.Cells(FirstRow, FirstCol), xlSheet.Cells(LastRow , LastCol)).Value = xT1  # THIS WORKS AS EXPECTED 



# Write to a range : data WITH  numpy data type
FirstRow = 2
FirstCol = 5
LastRow = FirstRow + len(xT2) - 1 # Number of records
LastCol =  FirstCol + len(xT2[0]) - 1        # Number of columns
xlSheet.Range(xlSheet.Cells(FirstRow, FirstCol), xlSheet.Cells(LastRow , LastCol)).Value = xT2  

这条线产生一个错误

TypeError:“numpy.int64”类型的对象无法转换为 COM VARIANT(但可以获取该对象的 buffer())

PS:在有人问之前(或建议另一种导出方式)。我故意使用win32,因为它是我发现写入现有的、预先准备好的excel文件并保留样式的唯一方法

PPS:受这篇文章的启发,我想出的一个解决方案是更改数据框每个元素的类型,我相信有更好的方法

def fnConvertdType (xListofList):
     newListofList = []
     for itemList in xListofList:
         xList = []
         for item in itemList:
             xList.append(np.asscalar(np.int16(item)))
         newListofList.append(xList)
     return newListofList
4

0 回答 0