pythonにおいてtxtファイルからある範囲の行を取り出しdataframe化したいです。


txt ファイルの中身には

日付  
1日中の1時時間刻みの  
風向、風速のデータが  
連続で記録されております。

例）  
2019 1 1 /n  
289 1 264 0.1 254 0.8 86 0.4 ....... /n  
70 0.8 270 0.56 287 0.67 30 0.25 ....... /n  
2019 1 2 /n  
274 2 255 0.13 257 0.22 254 0.12 ....... /n  
270 0.15 242 0.77 233 0.11 244 0.75 ....... /n

.....  
データから2～3行目の中身を取り出し奇数の所をdf[wind_dir]、偶数の所をdf[wind_speed]  
後、1行目中身を日付として後ろに時間を貼り付け、df[time]に作ればいいと思いますが  
pythonがまだ未熟なので、考え方をそのまま実行できないです。  
お手数ですが、良い方法を教えてください。  
風向、風速データはスペースで区分されており、奇数が風向、偶数が風速  
日付のデータもスペースで区分されております。




基本的に、毎日 00:00 からの24時間分のデータがあることを前提にしてみました。  
風向きは北北東を22.5度から始める16方位で、北を360.0度、静穏を0.0にしています。

[code]

    import pandas as pd
    
    # 時刻追加用文字列
    times = [
      '00:00','01:00','02:00','03:00','04:00','05:00','06:00','07:00',
      '08:00','09:00','10:00','11:00','12:00','13:00','14:00','15:00',
      '16:00','17:00','18:00','19:00','20:00','21:00','22:00','23:00'
    ]
    
    # ファイル読み取り
    with open('data.txt', mode='r') as f:
        lines = f.read().splitlines()
    
    datalist = []  # 全データリスト初期化
    for i in range(len(lines)//3):  # 1日3行毎のまとめ処理
        ix = i * 3
        # 日時データリスト作成
        date = lines[ix].strip().replace(' ','-') + ' '
        dates = [date + t for t in times]
    
        # 2行を連結して1日分のリスト作成
        winds = lines[ix + 1] + ' ' + lines[ix + 2]
        winds = [d for d in winds.split(' ') if d != '']
    
        # 風向、風速毎のリストへ分けて転記
        dirs = winds[0::2]
        spds = winds[1::2]
    
        # データが24時間分ちょうどでない時の調整(少ない場合は前にまとめたと想定)
        count = len(dirs)
        if count < 24:
            del dates[count:]
        elif count > 24:
            del dirs[24:]
            del spds[24:]
    
        # 1日分データの2次元リスト作成して全データリストへ追加
        winds = [[d,r,s] for d,r,s in zip(dates, dirs, spds)]
        datalist.extend(winds)
    
    # pandas DataFrame作成
    df = pd.DataFrame(datalist, columns=['time', 'wind_dir', 'wind_speed'])
    
    print(df)
    
[/code]

テキストデータがこれだと、

[code]

    2020 1 25
    292.5  4.3  292.5  5.4  292.5  6.6  292.5  6.6  292.5  6.3  292.5  7.0  292.5  7.3  292.5  6.2  315.0  5.2  315.0  3.9  315.0  4.6  22.5  3.3
    67.5  2.9  90.0  3.2  90.0  2.4  90.0  2.4  90.0  1.6  67.5  1.3  67.5  0.5  45.0  0.6  360.0  1.0  22.5  1.1  315.0  1.2  292.5  0.6
    2020 1 26
    247.5  0.8  292.5  0.6  225.0  0.3  247.5  0.4  337.5  1.2  337.5  0.9  22.5  0.7  180.0  2.1  180.0  2.0  135.0  1.9  135.0  0.5  22.5  0.4
    67.5  0.5  225.0  0.9  112.5  2.3  135.0  2.2  157.5  2.3  112.5  1.1  22.5  0.8  45.0  0.5  247.5  1.3  315.0  0.3  45.0  0.9  22.5  1.0
    2020 1 27
    45.0  0.5  337.5  0.9  292.5  0.8  292.5  0.8  67.5  1.1  67.5  1.0  90.0  1.3  180.0  1.3  180.0  0.6  135.0  0.5  135.0  2.0  112.5  1.8
    67.5  1.9  67.5  1.8  22.5  1.3  360.0  0.6  90.0  0.6  337.5  1.3  315.0  1.3  270.0  1.3  247.5  2.8  225.0  1.1  337.5  1.5  315.0  2.3
    
[/code]

結果はこうなります。

[code]

                   time wind_dir wind_speed
    0   2020-1-25 00:00    292.5        4.3
    1   2020-1-25 01:00    292.5        5.4
    2   2020-1-25 02:00    292.5        6.6
    3   2020-1-25 03:00    292.5        6.6
    4   2020-1-25 04:00    292.5        6.3
    ..              ...      ...        ...
    67  2020-1-27 19:00    270.0        1.3
    68  2020-1-27 20:00    247.5        2.8
    69  2020-1-27 21:00    225.0        1.1
    70  2020-1-27 22:00    337.5        1.5
    71  2020-1-27 23:00    315.0        2.3
    
    [72 rows x 3 columns]
    
[/code]




データファイルが

data.txt

[code]

    2019 1 1
    289 1 264 0.1 254 0.8 86 0.4
    70 0.8 270 0.56 287 0.67 30 0.25
    2019 1 2
    274 2 255 0.13 257 0.22 254 0.12
    270 0.15 242 0.77 233 0.11 244 0.75
    
[/code]

として、

  1. データをテキストファイルとして読み込み
  2. 上記のデータをリスト化
  3. 3行飛ばしでデータをまとめて、３つのDataFrame(date,wind_dir,wind_speed)をそれぞれ生成
  4. date は `pandas.to_datetime()` にて日時データに変換
  5. wind_dir/wind_speed は `DataFrame.stack()` にて縦並びのデータに変換
  6. wind_dir/wind_speed を`pandas.concat()` にて結合
  7. date を対応する行に結合

の手順にて目的のデータが生成できるかと思います。

以下は動作サンプルです。  
できるだけコメントをつけておきましたので、参考にどうぞ

[code]

    import pandas as pd
    
    # データ読み込み
    with open("data.txt") as f:
        data = [d.strip().split(' ') for d in f.readlines()]
    
    # 日付データを生成
    date = pd.to_datetime(pd.DataFrame(data[::3], columns=['year','month','day']))
    # 風向きデータ生成
    wind_dir = pd.DataFrame(data[1::3]).stack().rename('wind_dir')
    # 風速データ生成
    wind_speed = pd.DataFrame(data[2::3]).stack().rename('wind_speed')
    # 風向きデータと風速データを結合
    df = pd.concat([wind_dir, wind_speed], axis=1)
    # Indexを振り直す（level=0は日付データと結合する関係で残す必要あり）
    df = df.reset_index(level=0).reset_index(drop=True)
    # level_0 列のデータにより、日付データを引き当てる
    df['level_0'] = df['level_0'].map(date)
    # カラム名を修正しておく
    df = df.rename(columns={'level_0':'date'})
    
    print(df)
    #         date wind_dir wind_speed
    #0  2019-01-01      289         70
    #1  2019-01-01        1        0.8
    #2  2019-01-01      264        270
    #3  2019-01-01      0.1       0.56
    #4  2019-01-01      254        287
    #5  2019-01-01      0.8       0.67
    #6  2019-01-01       86         30
    #7  2019-01-01      0.4       0.25
    #8  2019-01-02      274        270
    #9  2019-01-02        2       0.15
    #10 2019-01-02      255        242
    #11 2019-01-02     0.13       0.77
    #12 2019-01-02      257        233
    #13 2019-01-02     0.22       0.11
    #14 2019-01-02      254        244
    #15 2019-01-02     0.12       0.75
    
[/code]

