所以我使用的是Jupyter 4.x和python 3.5,试图"上传"一个.csv
,但实际上只是想把它作为一个字符串捕获然后使用
setTimeout(function(){IPython.notebook.kernel.execute("stringData=StringIO(+"fr.result")");},5000);
允许FileReader()
对象有时间完成二进制字符串转换,然后将字符串保存到python变量中。我通过在控制台中打印整个Filereader()
文件来测试.csv
是否正常工作。但是出于某种原因,stringData在python端仍未定义。这是javascript单元格:
%%HTML
<input type="file" id="CSVFileInput" onchange="handleFiles(this.files)" value="upload csv">
<script>
var inputElement=document.getElementById('CSVFileInput');
function handleFiles() {
var file = inputElement.files[0];
var fr = new FileReader();
fr.readAsText(file);
var outputString=fr.result;
var command = "dataString ='"+outputString+"'";
setTimeout(function(){
IPython.notebook.kernel.execute(command);}
,5000);
}
inputElement.addEventListener("change", handleFiles, false);
</script>
在下一个单元格中,我测试输出并得到NameError
,因为dataString
未定义,这是下一个单元格:
dataString
另外,我是javascript的新手,但我想我应该重置超时?欢迎任何和所有的建议,我只觉得这是简单的方法。 PLS?当然,非常感谢!
答案 0 :(得分:1)
FileReader
方法是异步的,因此在您尝试将outputString
设置为结果时,不会加载任何数据。
处理此问题的正确方法是使用load
事件处理程序,因此您可以将代码修改为以下内容,而不是使用setTimeout()
,这对于异步处理是不可靠的:
function handleFiles() {
var file = this.files[0]; // "this" is the calling element
var fr = new FileReader();
fr.onload = function() {
var outputString = this.result; // here the data is ready. Now "this" = fr
var command = "dataString ='" + outputString + "'";
IPython.notebook.kernel.execute(command);
};
fr.readAsText(file); // invoked asynchronously
}
同时删除HTML中的内联JavaScript:
<input type="file" id="CSVFileInput" onchange="handleFiles(this.files)" value="upload csv">
到
<input type="file" id="CSVFileInput" title="upload csv">
(输入为value
时type=file
无效,请改为使用title
。然后使用以下代码来处理事件处理(在DOM加载之后):
document.getElementById("CSVFileInput").addEventListener("change", handleFiles);
function handleFiles() {
var file = this.files[0]; // "this" is the calling element
var fr = new FileReader();
fr.onload = function() {
var outputString = this.result; // here the data is ready. Now "this" = fr
var command = "dataString ='" + outputString + "'";
//IPython.notebook.kernel.execute(command);
console.log("Loaded file. Command:", command);
};
fr.readAsText(file); // invoked asynchronously
}
document.getElementById("CSVFileInput").addEventListener("change", handleFiles);
<input type="file" id="CSVFileInput" title="upload csv">
答案 1 :(得分:0)
所以,@ K3N绝对给了我一个有价值的异步功能拼图和课程。然而,主要的问题是python没有识别它从javascript接收的字符串输入,所以我想我会与所有人分享我的旅程。我最后将字符串转换为2d javascript数组,然后我shift()
关闭列名称的第一行,转换剩下的行,并清除所有来自英语的愚蠢的东西,阻止它工作(引号和撇号)。现在,当我从文件系统中读取它时,我可以pd.DataFrame(dict(zip(colNames,cols)))
运行我在同一.csv
上运行的所有计算。这是完整的脚本,基本上修复@ K3N向我展示了pythonify(arr)
函数:
<input type="file" id="CSVFileInput" title="upload csv">
function handleFiles() {
var file = this.files[0]; // "this" is the calling element
var fr = new FileReader();
fr.onload = function() {
var outputBuffer = this.result.split("\r"); //split on row delimeter
var temp=[];
var command;
outputBuffer.forEach(function(element){
element=element.replace("\n",""); //each was also delimeter by this, so strip it
temp.push(element.split("\t")); //split on cols
});
outputBuffer=temp;//yay now outputBuffer is 2d array
var names=outputBuffer.shift(); //pop names rown from output Buffer
temp=[]; //reset temp
for(let i=0 ; i<outputBuffer[0].length ; i++){ //transpose remaining rows to provide arrays for names
temp[i]=[];
for(let j=0; j<outputBuffer.length ; j++){
temp[i][j]=outputBuffer[j][i];
}
}
outputBuffer=temp; //yay now is transposed
command="colNames ="+pythonify(names); //declare colNames array on python side
IPython.notebook.kernel.execute(command); //send command to kernel
for(let i=0 ; i< outputBuffer.length ; i++){ //loop appends columns on python side
command="cols.append("+pythonify(outputBuffer[i])+")";
IPython.notebook.kernel.execute(command); //send command to kernel
}
};
fr.readAsText(file); // invoked asynchronously
}
function pythonify (arr){ //turns javascript array into string representation of python list
var out= '[';
for(let i=0 ; i<arr.length ; i++){
var element=arr[i];
element=element.replace(/\"/g,'\\"').replace(/'/g,"\\'"); //replaces quotes with python escaped version
out+='r"'+element+'"';
if(i<arr.length-1){ //skip last comma
out+=',';
}
}
out+=']';
return out;
}
document.getElementById("CSVFileInput").addEventListener("change", handleFiles);