LISPデータをRapidMinerにインポートする(CSV、…)
-
26-10-2019 - |
質問
LISP形式のデータがあり、RapidMinerでそれらを処理する必要があります。私はLispとRapidMinerにも初めてです。 RapidMinerはLISPを受け入れません(それは言語のプログラミングだからだと思います)ので、おそらくLISPフォームを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)
...)
どんなアドバイスにも感謝しています。
解決
LISPのパーサーがLISPユーザーが利用できるという事実を利用できます。このデータの問題は、一部の値にコロンが含まれており、共通LISPのパッケージ名セパレーターが使用されることです。私はあなたの質問を解決するためにいくつかの機能する一般的な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))))
主な関数はデータファイルからCSVで、 (data-file-to-csv "path-to-input-file" "path-to-output-file")
このコードをロードした後の一般的なLISP REPLで。
編集:いくつかの追加の考え
すべての値のパッケージ定義をコロンで追加するのではなく、正規表現検索を行い、データに置き換えて、すべての値の周りに引用符( ")を追加するのは簡単です。これにより、LISPがすぐに文字列として解析されます。その場合、線 for string = (remove #\| (write-to-string value :case :downcase))
削除することができます string
置き換えられます value
のすべての行で case
声明。
データの規則性が高いため、LISPの定義を完全に正しく解析する必要はありません。代わりに、正規表現でデータを抽出することができます。テキストファイルの正規性ベースの変換に特に適した言語は、awkやperlのようなジョブにとっては問題ありません。