PyCall issue appearing with Julia 0.5.1 (0.4.7 worked fine)

pycall

#1

Hi all.
I am using Windows 7 and the Python version that comes with Julia Pro.
The code below runs fine for Julia 0.4.7 but with Julia 0.5.1 I get an error which is realted to the last pycall(pyDF[“to_excel”], …

The error is

ERROR: LoadError: KeyError: key "to_excel" not found

Can anyone help me with this?
I unsuccessfully tried a different syntax for the pycall (e.g. py"…" with interpolation and without)

Here is the code:

using DataFrames,PyCall

type Chart	
	sheet::UTF8String
	chartDict::Dict{AbstractString,Dict{AbstractString,Any}}
	location::UTF8String
end

type ExcelSheet
	name::UTF8String
	data::DataFrame
end

type ExcelData
	sheets::Array{ExcelSheet,1}
	charts::Array{Chart,1}
end

function create_custom_dict(df::DataFrame)	
	header=names(df)
	d=Dict{AbstractString,Array{Any,1}}()
	for i=1:length(header)			
		d[string(header[i])]=df[i]
	end
	return d
end

function write_statistics{T<:AbstractString}(excelData::ExcelData,statsfile::T)
	#writing an Excel file seems very slow if the file already exists
	isfile(statsfile)&&rm(statsfile)
	
	writer=writeDFtoExcel(excelData,statsfile,0,0)
	workbook = writer[:book]
	writer[:save]()
	return nothing
end

function writeDFtoExcel{T<:AbstractString}(excelData::ExcelData,file::T,row::Int,col::Int)
	@assert min(row,col)>=0	
	writer = pyModPandas.ExcelWriter(file, engine = "xlsxwriter")
	for xlSheet in excelData.sheets
		df=xlSheet.data
	    sheet=xlSheet.name
		#create python dataframe	
		dataDict = create_custom_dict(df)
		pyDF = pyModPandas.DataFrame(dataDict,columns=names(df))		
		#this line worked in Julia 0.4
		pycall(pyDF["to_excel"],PyAny,writer, header=false,index=false, sheet_name = sheet,startrow=row, startcol=col, encoding="utf-8")  #index=false suppress the rowcount		
		#DataFrame.to_excel(excel_writer, sheet_name='Sheet1', na_rep='', float_format=None, columns=None, header=True, index=True, index_label=None, startrow=0, startcol=0, engine=None, merge_cells=True, encoding=None, inf_rep='inf')
	end
	return writer	
end

pyModPandas=pywrap(pyimport("pandas"))

dta=rand(20,200);
sh=ExcelSheet("mi",DataFrame(dta));
xxl=ExcelData([sh],Array(Chart,0));

f="C:\\temp\\somefile_yxy.xlsx"
test=write_statistics(xxl,f)

#2

Possibly this is converting to an unwanted Julia type, whereas you want the raw Python object? See also https://github.com/JuliaPy/PyCall.jl/pull/384, which should fix this in the next tagged PyCall release.

You can force it to return the raw Python object with pycall(pyModPandas.DataFrame, PyObject, dataDict,columns=names(df))


#3

Thank you. This does indeed resovle my issue.

A posteriori it seems the error message (KeyError) should have led me to investigate the type of the variable, especially given that my variable is called py DF.