64079


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がまだ未熟なので、考え方をそのまま実行できないです。  
お手数ですが、良い方法を教えてください。  
風向、風速データはスペースで区分されており、奇数が風向、偶数が風速  
日付のデータもスペースで区分されております。


CC BY-SA 4.0
2020-03-24T04:11:30.427
64066
2020-03-25T13:20:57.373
37823
question
python python3
pythonにおいてtxtファイルからある範囲の行を取り出しdataframe化したいです。


データファイルが

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]


CC BY-SA 4.0
2020-03-24T07:01:36.373
64071
2020-03-24T07:01:36.373
24801
64066
answer


基本的に、毎日 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]


CC BY-SA 4.0
2020-03-24T08:54:24.933
64079
2020-03-24T09:01:06.113
2020-03-24T09:01:06.113
26370
26370
64066
answer


以下は `dataframe.read_table()` を使う方法です。

**Python script**

[code]

    import pandas as pd
    
    data_file = 'wind_data.dat'
    
    date_time = pd.read_table(
      data_file, header=None, parse_dates=[0], skiprows=lambda x: x%3!=0
    ).apply(
      lambda x: pd.date_range(x[0], periods=24, freq='1H'),
      axis=1, result_type='expand'
    ).values.flatten()
    
    wind = pd.read_table(
      data_file, header=None, sep=r' +', engine='python', skiprows=lambda x: x%3==0
    ).values.flatten()
    
    df = pd.DataFrame({
      'time': date_time, 'wind_dir': wind[::2], 'wind_speed': wind[1::2]
    })
    
    print(df)
    
[/code]

**wind_data.dat**

[code]

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

**実行結果**

[code]

                      time  wind_dir  wind_speed
    0  2019-01-01 00:00:00     289.0        1.00
    1  2019-01-01 01:00:00     264.0        0.10
    2  2019-01-01 02:00:00     254.0        0.80
    3  2019-01-01 03:00:00      86.0        0.40
                            :
    21 2019-01-01 21:00:00      30.0        0.25
    22 2019-01-01 22:00:00      20.0        0.40
    23 2019-01-01 23:00:00      10.0        0.60
    24 2019-01-02 00:00:00     274.0        2.00
    25 2019-01-02 01:00:00     255.0        0.13
    26 2019-01-02 02:00:00     257.0        0.22
    27 2019-01-02 03:00:00     254.0        0.12
                            :
    45 2019-01-02 21:00:00     242.0        0.77
    46 2019-01-02 22:00:00     233.0        0.11
    47 2019-01-02 23:00:00     244.0        0.75
    
[/code]


CC BY-SA 4.0
2020-03-24T19:04:19.827
64089
2020-03-25T13:20:57.373
2020-03-25T13:20:57.373
64066
answer