emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [O] org-mode and python pandas


From: Dror Atariah
Subject: Re: [O] org-mode and python pandas
Date: Wed, 29 Apr 2015 09:12:34 +0200

Using the tabulate python module it is possible to have the following "inline" workaround:

------------8<------------8<------------8<------------8<------------8<------------8<------------8<------------
#+BEGIN_SRC python :results raw
import pandas as pd
import numpy as np
from tabulate import tabulate

df = pd.DataFrame(np.random.random((4,3)), columns=['A','B','C'])
print("foo")
return(tabulate(df, headers="keys", tablefmt="orgtbl"))
#+END_SRC

#+RESULTS:
|   |        A |        B |        C |
|---+----------+----------+----------|
| 0 | 0.754799 | 0.492722 | 0.144595 |
| 1 | 0.198475 | 0.417721 | 0.083459 |
| 2 | 0.645011 | 0.444857 | 0.278874 |
| 3 | 0.314883 |   0.7521 | 0.789418 |
------------8<------------8<------------8<------------8<------------8<------------8<------------8<------------

However, this is not optimal, mainly because it pollutes the code block. Note, that the :results is set to `raw`.

A brief discussion with Dov, yielded the following better workaround:
------------8<------------8<------------8<------------8<------------8<------------8<------------8<------------
(setq org-babel-python-wrapper-method "
def main():
%s

res = main()
if 'pandas.core.frame.DataFrame' in str(type(res)):
    from tabulate import tabulate
    out = tabulate(res, headers='keys', tablefmt='orgtbl')
else:
    out = str(res)

open('%s', 'w').write(out)")
------------8<------------8<------------8<------------8<------------8<------------8<------------8<------------

This allows a nice output of pandas.DataFrame (again when using :results raw). Unfortunately, this wrapper has no influence in the case when :session is used. To that end, it is possible to hack 

------------8<------------8<------------8<------------8<------------8<------------8<------------8<------------
(defun org-babel-python-evaluate-session
    (session body &optional result-type result-params)
  "Pass BODY to the Python process in SESSION.
If RESULT-TYPE equals 'output then return standard output as a
string.  If RESULT-TYPE equals 'value then return the value of the
last statement in BODY, as elisp."
  (let* ((send-wait (lambda () (comint-send-input nil t) (sleep-for 0 5)))
 (dump-last-value
  (lambda
    (tmp-file pp)
    (mapc
     (lambda (statement) (insert statement) (funcall send-wait))
     (if pp
 (list
  "import pprint"
  (format "open('%s', 'w').write(pprint.pformat(_))"
  (org-babel-process-file-name tmp-file 'noquote)))
       (list (format "_org_tmp = _;                                                                        
if 'pandas.core.frame.DataFrame' in str(type(_org_tmp)):
    from tabulate import tabulate
    _org_out = tabulate(_org_tmp, headers='keys', tablefmt='orgtbl')
else:
    _org_out = _org_tmp

open('%s', 'w').write(str(_org_out))"
     (org-babel-process-file-name tmp-file
                                                          'noquote)))))))
 (input-body (lambda (body)
       (mapc (lambda (line) (insert line) (funcall send-wait))
     (split-string body "[\r\n]"))
       (funcall send-wait)))
         (results
          (case result-type
            (output
             (mapconcat
              #'org-babel-trim
              (butlast
               (org-babel-comint-with-output
                   (session org-babel-python-eoe-indicator t body)
                 (funcall input-body body)
                 (funcall send-wait) (funcall send-wait)
                 (insert org-babel-python-eoe-indicator)
                 (funcall send-wait))
               2) "\n"))
            (value
             (let ((tmp-file (org-babel-temp-file "python-")))
               (org-babel-comint-with-output
                   (session org-babel-python-eoe-indicator nil body)
                 (let ((comint-process-echoes nil))
                   (funcall input-body body)
                   (funcall dump-last-value tmp-file
                            (member "pp" result-params))
                   (funcall send-wait) (funcall send-wait)
                   (insert org-babel-python-eoe-indicator)
                   (funcall send-wait)))
               (org-babel-eval-read-file tmp-file))))))
    (unless (string= (substring org-babel-python-eoe-indicator 1 -1) results)
      (org-babel-result-cond result-params
results
        (org-babel-python-table-or-string results)))))
------------8<------------8<------------8<------------8<------------8<------------8<------------8<------------

This works, but I would be surprised if this hack meets org-mode's standards. Nevertheless, maybe someone would find it useful.

What do you think? How can it be improved?

Best,
Dror

reply via email to

[Prev in Thread] Current Thread [Next in Thread]