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

问题描述 投票:0回答:2

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

javascript html python-3.x jupyter-notebook filereader
2个回答
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">

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);
© www.soinside.com 2019 - 2024. All rights reserved.