将LISP数据导入到RapidMiner(CSV,...)

问题描述:

我有LISP格式的数据,我需要在RapidMiner中处理它们。我是LISP和RapidMiner的新手。 RapidMiner不接受LISP(我猜这是因为它是编程语言),所以我可能需要以某种方式将LISP格式转换为CSV或类似的东西。代码的小例子:将LISP数据导入到RapidMiner(CSV,...)

(def-instance Adelphi 
    (state newyork) 
    (control private) 
    (no-of-students thous:5-10) 
    ...) 
(def-instance Arizona-State 
    (state arizona) 
    (control state) 
    (no-of-students thous:20+) 
    ...) 
(def-instance Boston-College 
    (state massachusetts) 
    (location suburban) 
    (control private:roman-catholic) 
    (no-of-students thous:5-10) 
    ...) 

我会为任何建议非常感激。

+0

通常适用于您的Lisp数据的软件是否可用?如果你可以使用它的'def-instance'定义,这将为你省去编写'def-instance'或者自己解析这些调用的麻烦。 –

+0

我收到了这种格式的数据,我不知道它们来自哪里。我的任务是将这个lisp方案转换成可以用RapidMiner处理的某种表格数据。我真的很想避免自己编写一些解析器/转换器:) – svobol13

您可以利用Lisp解析器可供Lisp用户使用的事实。这个数据的一个问题是一些值包含冒号,而在Common Lisp中使用包名称分隔符。我编写了一些可用的Common Lisp代码来解决你的问题,但是我必须通过定义适当的包来解决上述问题。

这里是你的例子在你的问题留出了代码,那当然必须要延长(以下即是在它已经使用了相同的模式)的一切:

(defpackage #:thous 
    (:export #:5-10 #:20+)) 
(defpackage #:private 
    (:export #:roman-catholic)) 

(defstruct (college (:conc-name nil)) 
    (name "") 
    (state "") 
    (location "") 
    (control "") 
    (no-of-students "")) 

(defun data->college (name data) 
    (let ((college (make-college :name (write-to-string name :case :capitalize)))) 
    (loop for (key value) in data 
     for string = (remove #\| (write-to-string value :case :downcase)) 
     do (case key 
      (state (setf (state college) string)) 
      (location (setf (location college) string)) 
      (control (setf (control college) string)) 
      (no-of-students (setf (no-of-students college) string)))) 
    college)) 

(defun read-data (stream) 
    (loop for (def-instance name . data) = (read stream nil nil) 
    while def-instance 
    collect (data->college name data))) 

(defun print-college-as-csv (college stream) 
    (format stream 
      "~a~{,~a~}~%" 
      (name college) 
      (list (state college) 
       (location college) 
       (control college) 
       (no-of-students college)))) 

(defun data->csv (in out) 
    (let ((header (make-college :name "College" 
           :state "state" 
           :location "location" 
           :control "control" 
           :no-of-students "no-of-students"))) 
    (print-college-as-csv header out) 
    (dolist (college (read-data in)) 
     (print-college-as-csv college out)))) 

(defun data-file-to-csv (input-file output-file) 
    (with-open-file (in input-file) 
    (with-open-file (out output-file 
         :direction :output 
         :if-does-not-exist :create 
         :if-exists :supersede) 
    (data->csv in out)))) 

主要功能是data-file-to-csv,加载此代码后可以在Common Lisp REPL中使用(data-file-to-csv "path-to-input-file" "path-to-output-file")调用。

编辑:一些额外的想法

它实际上会更容易些,而不是增加包装的定义对于所有的值用冒号,做一个正则表达式搜索和替换过来的数据添加身边所有的引号(“)值。这将使Lisp语言解析他们作为字符串的时候了。在这种情况下,该行for string = (remove #\| (write-to-string value :case :downcase))可能被删除,string可以在case声明的所有行与value取代。

由于数据的高规律性,实际上甚至不需要正确解析Lisp定义,而是,你可以用正则表达式提取数据。一种特别适合基于正则表达式的文本文件转换的语言应该适用于AWK或Perl这样的工作。