尝试将csv上传捕获为字符串Jupyter

时间:2017-12-20 04:03:03

标签: javascript html python-3.x jupyter-notebook filereader

所以我使用的是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?当然,非常感谢!

2 个答案:

答案 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">

(输入为valuetype=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);