質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.37%

数値,テキスト混同の.DATファイルに対して,ファイル内のデータを逐次,配列に格納したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,357

basketball

score 5

前提・実現したいこと

やりたいこと:Python3.xで数値とテキスト混合のデータ(.datファイル)を読み込むプログラムを作成しています.
最終的な目的:格納した配列からグラフを作成したり,数値計算をする.
→まず,生データを整理したい.

■ データの中身
このデータはある計測装置から直接吐き出されるもので,
ダブ区切りでもカンマ区切りでもなく,独自のフォーマットです.


data (A)        =   8.449E-19  -1.406E-04  -1.711E-04   8.832E-04   1.156E-03
(スペース連続)      1.985E-03   1.051E-03   8.782E-04   5.164E-04   3.921E-04
(改行)
data (B)       =  -9.936E-06  -1.504E-04  -1.712E-04   8.980E-04   1.274E-03
(スペース連続)     2.044E-03   1.040E-03   8.514E-04   4.703E-04   3.700E-04
(改行)
...と以下続く.----------------------------------------------------------------
※数字が5つ続いたら,改行して,先頭を揃えてまた5つ数字がならぶ.'-'符合分はずれる
※.DATファイルはテキストです.

■ 実現したいこと
STEP1:DATA.DATを読み込む.先頭から1行ずつ読んでいく.
STEP2: data (A)    =   という名前がきたらdata_A 名前の空配列を作成し,8.449E-19 ~ 3.921E-04まで(上の事例では2行分)格納
STEP3: dataB以降も同様.ループで最後(データがないところ)まで続ける.

該当のソースコード

import re
import pandas as pd

pattern=re.compile(' +') # 正規表現でスペースが1個以上続くものを抽出
ifile = 'DATA.DAT' # 本文のようなデータ
fout = open('c'+ifile.split('.')[0]+'.csv','tw') # 出力ファイル名を入力ファイルから命名してopen

with open(ifile,'tr') as fin:
    for iline in fin:
        fout.write(pattern.sub(',',iline)) #一文字以上のスペースをカンマに置換→ここのループで処理したい

fout.close()


Dummy_names = [ 'c{0:02d}'.format(i) for i in range(10) ] #疑似的なヘッダー
df = pd.read_table('cDATA.csv','r',names=Dummy_names, delimiter = ",") #今はとりあえずDataFrameで中身を見ている

試したこと

1.pandas でDateFrameとして読み込み.
→1つの1つの要素に1行分すべてはいってしまう.
例:「data (A)        =   8.449E-19  -1.406E-04  -1.711E-04   8.832E-04   1.156E-03」ここまで1要素にはいってしまう.

2.スペース区切りとも言えない感じなので,with openでパスを指定し,一度,CSVに変換する.スペースを','に置きかえ(記載ソース)
↓結果
,Y,IN(I),=,8.449E-19,-1.406E-04,-1.711E-04,8.832E-04,1.156E-03
,1.985E-03,1.051E-03,8.782E-04,5.164E-04,3.921E-04

→これをPandasのread_csvで読む
1要素ずつデータは格納されたが,さらに後処理するの

ここからまとめるのもいいが,
初期のforループで配列格納を逐次行いたい

補足情報(FW/ツールのバージョンなど)

Spyderで作業しています.

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • meg_

    2020/02/23 22:43

    ・コードは「コードの挿入」で記入してください。
    ・DATファイルの中身はテキストなのですか?

    キャンセル

  • basketball

    2020/02/23 22:57

    コードの挿入にて記載・修正しました
    DATの中身はテキストです

    キャンセル

回答 1

checkベストアンサー

+1

以下のような感じで正規表現で=~改行~改行改行の単位で抽出していけばよいかと思います。

import re
from io import StringIO

# テストデータ
s = """data (A)        =   8.449E-19  -1.406E-04  -1.711E-04   8.832E-04   1.156E-03
                    1.985E-03   1.051E-03   8.782E-04   5.164E-04   3.921E-04

data (B)       =  -9.936E-06  -1.504E-04  -1.712E-04   8.980E-04   1.274E-03
                   2.044E-03   1.040E-03   8.514E-04   4.703E-04   3.700E-04

"""
datas = StringIO(s).read() # 全部読み込む
datas += '\n\n' # 念のため番兵をつける

# 1行分の文字列を数値リストに
def to_list(s):
    return [float(e) for e in re.split(r'\s+', s.strip(' '))]

data = {}
for m in re.finditer(r'data \((.*?)\).*?=(.*?)\n(.*?)\n\n', datas, re.MULTILINE):
    line = to_list(m.group(2)) + to_list(m.group(3)) # 2行 -> 1行の数値リストに
    data[m.group(1)] = line

print(data)
#{'A': [8.449e-19, -0.0001406, -0.0001711, 0.0008832, 0.001156, 0.001985, 0.001051, 0.0008782, 0.0005164, 0.0003921], 'B'
#: [-9.936e-06, -0.0001504, -0.0001712, 0.000898, 0.001274, 0.002044, 0.00104, 0.0008514, 0.0004703, 0.00037]}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/03/07 23:16

    回答ありがとうございます。
    上記のコードで ret 内にデータを格納することができましたが,

    ■ 実現したいこと:STEP2,STEP3の
    「data_A」なる変数名に格納→次の変数も逐次格納する
    のやり方がわかりません.

    空行列を先にたくさん作って,接頭語と一致したらその値を格納するイメージをもって
    作っていますが,うまくいきません.

    なにか方法はないでしょうか.

    キャンセル

  • 2020/03/07 23:24

    回答修正しました。
    data_Aなりの変数に格納するのは煩わしいのでdataという辞書に'A'などをキーとして格納しています。

    キャンセル

  • 2020/03/07 23:51

    回答ありがとうございました.回答を参考に作成してみます.

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る