Question

J'ai données sous forme LISP et je dois les traiter dans RapidMiner. Je suis nouveau à LISP et aswell RapidMiner. RapidMiner n'accepte pas le LISP (je suppose que c'est parce qu'il est langage de programmation) donc j'ai besoin probablement d'une certaine manière à convertir forme LISP au format CSV ou quelque chose comme ça. Petit exemple de code:

(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)
   ...)

Je serais vraiment reconnaissant pour tout conseil.

Était-ce utile?

La solution

Vous pouvez utiliser le fait que l'analyseur de Lisp est disponible à l'utilisateur Lisp. Un problème avec ces données est que certaines valeurs contiennent côlons, est utilisé avec le séparateur de nom du package en Common Lisp. Je fait un certain travail de code Common Lisp pour résoudre votre question, mais j'ai dû contourner le problème mentionné en définissant des paquets appropriés.

Voici le code, qui doit évidemment être étendue (suivant les mêmes motifs qui sont déjà utilisés dans celui-ci) pour tout ce que vous avez laissé dans l'exemple dans votre question:

(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))))

La fonction principale est données à fichier csv, qui peut être appelé avec (data-file-to-csv "path-to-input-file" "path-to-output-file") dans un Common Lisp REPL après le chargement de ce code.

EDIT: quelques réflexions supplémentaires

Il serait effectivement plus facile, au lieu d'ajouter des définitions de paquet pour toutes les valeurs avec deux points, de faire une recherche d'expression régulière et remplacer sur les données à ajouter des guillemets ( ") autour de toutes les valeurs. Cela fera Lisp les analyser sous forme de chaînes tout de suite. dans ce cas, la for string = (remove #\| (write-to-string value :case :downcase)) ligne pourrait être retirée et remplacée par string value dans toutes les lignes de la déclaration de case.

En raison de la grande régularité des données, il ne devrait même pas réellement nécessaire pour analyser les définitions Lisp correctement à tous. Au lieu de cela, vous pouvez simplement extraire les données avec des expressions régulières. Une langue particulièrement adaptée à la transformation basée sur les expressions régulières des fichiers texte devrait être très bien pour ce travail, comme AWK ou Perl.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top