2015-08-08 1 views
10

Eseguo un server iPython Notebook e vorrei che gli utenti fossero in grado di scaricare un dataframe panda come file csv in modo che possano utilizzarlo nel proprio ambiente. Non ci sono dati personali, quindi se la soluzione prevede la scrittura del file sul server (cosa che posso fare) e poi il download di quel file, sarei felice con quello.Download CSV da un notebook iPython

+0

Non credo ipython ha alcuna funzione per risolvere quello che si sta chiedendo, ma si può sempre codificare una routine in python che esegue la scarica e includilo nel notebook per i tuoi utenti. Solo un'idea Spero che sia d'aiuto. – lrnzcig

+0

Grazie lrnzcig: questo è quello che mi sembra. Potrei provare il tuo suggerimento. –

+0

Salve, è possibile scrivere il dataframe in un csv con 'pd.to_csv()' e quindi aprire il csv direttamente dal server ipython, e quindi il file> Download? – johnchase

risposta

1

È possibile utilizzare il fatto che il notebook in grado di visualizzare html per gli oggetti, e gli URL di dati, per rendere il contenuto di uno scaricabile csv:

import urllib 

class CSV(object): 
    def _repr_html_(self): 
     html = [] 

     html.append("{},{},{}".format(
       "user", 
       "age", 
       "city" 
      ) 
     ) 

     html.append("{},{},{}".format(
       "Alice", 
       "39", 
       "New York" 
      ) 
     ) 

     html.append("{},{},{}".format(
       "Bob", 
       "30", 
       "Denver" 
      ) 
     ) 

     html.append("{},{},{}".format(
       "Carol", 
       "27", 
       "Tulsa" 
      ) 
     ) 


     export = '\n'.join(html) 
     export = urllib.quote(export.encode("utf-8")) 
     csvData = 'data:application/csv;charset=utf-8,' + export 
     return "<a download='export.csv' href='{}' target='_blank'>csv file</a>".format(csvData) 

CSV() 
9

ne dite di usare la classe FileLinks da IPython? Lo uso per fornire accesso ai dati direttamente dai notebook Jupyter. Supponendo che i dati sono in panda dataframe p_df:

from IPython.display import Filelink, FileLinks 

p_df.to_csv('/path/to/data.csv', index=False) 
p_df.to_excel('/path/to/data.xlsx', index=False) 

FileLinks('/path/to/') 

Esegui questo come una cella notebook e il risultato sarà un elenco di link a file scaricabili direttamente dal notebook. '/path/to' deve essere accessibile per l'utente del notebook, ovviamente.

3

Se si vuole evitare di memorizzare CSV sul server, è possibile utilizzare questa alternativa Javascript che creare il CSV sul lato client:

from IPython.display import Javascript 
js_download = """ 
var csv = '%s'; 

var filename = 'results.csv'; 
var blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); 
if (navigator.msSaveBlob) { // IE 10+ 
    navigator.msSaveBlob(blob, filename); 
} else { 
    var link = document.createElement("a"); 
    if (link.download !== undefined) { // feature detection 
     // Browsers that support HTML5 download attribute 
     var url = URL.createObjectURL(blob); 
     link.setAttribute("href", url); 
     link.setAttribute("download", filename); 
     link.style.visibility = 'hidden'; 
     document.body.appendChild(link); 
     link.click(); 
     document.body.removeChild(link); 
    } 
} 
""" % data_in_dataframes.to_csv(index=False).replace('\n','\\n').replace("'","\'") 

Javascript(js_download) 

Fondamentalmente, si crea una stringa CSV in python dal pd dataframe e usarlo in un piccolo script js che creates a CSV file on the client side e aprire una finestra di dialogo di salvataggio per salvarlo sul computer dell'utente. Ho provato il mio iPenone env e funziona come un fascino!


Nota che sto sfuggendo allo \n. Se non lo faccio, la stringa di script js avrà la variabile CSV scritta su più righe.

Ad esempio, print "var csv = '%s'" % industries_revenues.to_csv(index=False).replace('\n','\\n') risultati di questo:

var csv = 'Industry,sum_Amount\nBanking,65892584.0\n(...)Finance,20211917.0\n' 

Invece di print "var csv = '%s'" % industries_revenues.to_csv(index=False) senza \n sfuggire che i risultati in un multiplo allineati e quindi con errori JavaScript:

var csv = 'Industry,sum_Amount 
Banking,65892584.0 
(...) 
Finance,20211917.0 
' 

Ho anche sfuggire il ' non per rompere la stringa variabile in javascript.

+0

Ricevo un errore Javascript per aggiungere output! SyntaxError: missing; prima dell'affermazione Vedere la console Javascript del browser per ulteriori dettagli. – AlexLordThorsen

1

Per non troppo grandi tavoli è possibile utilizzare il seguente codice:

import base64 
import pandas as pd 
from IPython.display import HTML 

def create_download_link(df, title = "Download CSV file", filename = "data.csv"): 
    csv = df.to_csv() 
    b64 = base64.b64encode(csv.encode()) 
    payload = b64.decode() 
    html = '<a download="{filename}" href="data:text/csv;base64,{payload}" target="_blank">{title}</a>' 
    html = html.format(payload=payload,title=title,filename=filename) 
    return HTML(html) 

df = pd.DataFrame(data = [[1,2],[3,4]], columns=['Col 1', 'Col 2']) 
create_download_link(df)