

以下のようなcsvファイルを読み取ってデータをまとめる作業を行おうと考えています。

[code]

    ダウンロードした時刻：2019/11/11 16:04:33                  
    
                    寺泊  寺泊
    年   月   日   時   風速(m/s) 風向
    
    2016    12  23  5   9.6 南南東
    2016    12  23  6   9.8 南東
    2016    12  23  7   10.6　東
    2016    12  23  8   10.4　北東
    2016    12  23  9   10.5　西
    2016    12  23  10  9.1 西
    2016    12  23  11  8.1 西北西
    2016    12  23  12  7.8 西北西
    2016    12  23  13  6.8 西北西
    2016    12  23  14  6.3 北西
    2016    12  23  15  6.2 北西
    2016    12  23  16  6.5 北北西
    2016    12  23  17  6.3 北北西
    2016    12  23  18  6.3 北
    2016    12  23  19  5.4 南西
    2016    12  23  20  3.9 西南西
    2016    12  23  21  4   南南西
    2016    12  23  22  4.6 南
    2016    12  23  23  4   南
    
[/code]

処理の方法は  
➀特定の風向を満たしている風速の値を2乗する。  
ex)上記のデータの場合  
16方位で南南西・南西・西南西・西・西北西・北西・北北西を満たす風速の値を2乗  
(10.5)^2+(9.1)^2+(8.1)^2+(7.8)^2+(6.8)^2+(5.3)^2+(6.2)^2+・・・・・

➁次に角度補正を行いたいため、風向によってcosθを風速の2乗の値にかける  
ex)上記のデータの場合  
・風向は16方位に区切られているので、隣り合う方位の角度の間隔は22.5°  
西を正面とすると(このデータでは西とした）  
西北西と西南西は22.5°、北西と南西は45°、北北西と南南西は67.5°

・この西を基準とした角度を基に、風速の2乗値にそれぞれcosθをかける  
(10.5)^2×cos(0)+(9.1)^2×cos(0)+  
(8.1)^2×cos(22.5)+(7.8)^2×cos(22.5)+(6.8)^2×cos(22.5)+  
(6.3)^2×cos(45)+(6.2)^2×cos(45)+  
(6.5)^2×cos(67.5)+(6.3)^2×cos(67.5)+  
(5.4)^2×cos(45)+  
(3.9)^2×cos(22.5)+  
(4)^2×cos(67.5)

➂ ➁の値を全部足し合わせる。

このような処理を行いたいと考えています。

現在特定の風向を満たす、風速の値を2乗して、それを足し合わせる  
というところまでは動きましたが  
➁のような、ある風向にはcos(22.5)をかけ、ある風向にはcos(45)をかけるといった処理ができずに悩んでおります。  
また、このデータでは西を基準にしましたが、ほかのデータでは東や南東や北北東など基準はそれぞれ違うので、処理するデータに合わせて、プログラムを少し書き換えて動かせるようなものをつくりたいと考えています。

今現在のプログラムを以下に示します。  
長い文章になって申し訳ございません。  
このような処理ができるような方法をご教示いただけないでしょうか。  
どうか回答よろしくお願いいたします。

* * *
[code]

    import csv
    
    f = open("寺泊test.csv", "r")
    reader = csv.reader(f)
    next(reader); next(reader); next(reader); next(reader); next(reader)
    
    Direction = ['南南西','南西','西南西','西','西北西','北西','北北西']
    
    sum = 0
    for row in reader:
      if not row[4].strip(): # 空行スキップ
        continue
      colE = float(row[4])
      if (colE >= 0) and (row[5] in Direction):
          sum += pow(colE,2)
    
    print(sum)
    f.close()
    
[/code]

* * *


CC BY-SA 4.0
2020-01-24T07:24:14.350
62513
2020-03-10T09:01:15.340
2020-01-24T12:19:55.963
3060
36312
question
python csv
python で csvファイルのデータを処理したい。


風速(ベクトル)の基準方位成分値を積算する、と解釈すると、以下の範囲が積算対象になります。

[code]

    (基準方位-(1/2)π, 基準方位+(1/2)π)
    
[/code]

基準方位が「西」であれば「南南西」から「北北西」になります(それら以外の方位の場合、「西」方位成分の値は 0 以下になる)。

以下は pandas のデータフレームを利用して、各基準方位での積算値を計算しています。

[code]

    import pandas as pd
    from math import cos, pi
    
    Direction_16 = [
      '北', '北北東', '北東', '東北東',
      '東', '東南東', '南東', '南南東',
      '南', '南南西', '南西', '西南西',
      '西', '西北西', '北西', '北北西'
    ]
    l = len(Direction_16)
    Cosine = [0.0 if i%8==4 else cos(i*2*pi/l) for i in range(l)]
    
    def load_csv(f):
      df = pd.read_csv(
        f, skipinitialspace=True, skiprows=4,
        names=['year', 'month', 'day', 'hour', 'velocity', 'direction'],
        converters={'direction': str.strip}
      )
    
      return df.assign(
        sq_velocity = df.velocity**2,
        dir_idx = pd.Series(pd.Categorical(
          df.direction, categories=Direction_16)).cat.codes,
        )
    
    def calc(df, src):
      ## Get region: (src-(1/2)π, src+(1/2)π)
      sidx = Direction_16.index(src)
      beg = ((sidx - 4) + l) % l
      end = (sidx + 4) % l
      op = 'and' if beg < end else 'or'
    
      return df.query(f'{beg} < dir_idx {op} dir_idx < {end}')\
               .apply(
                 lambda r:
                   pd.Series((
                     r.sq_velocity,
                     r.sq_velocity*Cosine[abs(r.dir_idx-sidx)])),
                 axis=1)\
               .sum()
    
    if __name__=='__main__': 
      df = load_csv('test.csv')
      print(f'基準方位  二乗和  二乗射影和')
      for d in Direction_16:
        sq, proj = calc(df, d)
        pad = ' '*(4-len(d))
        print(f'{pad+d+pad} {sq:7.2f} {proj:9.2f}')
    
    =>
    基準方位  二乗和  二乗射影和
       北     480.61    313.21
     北北東   420.28    267.43
      北東    342.15    247.03
     東北東   356.25    255.68
       東     408.72    292.02
     東南東   445.88    313.32
      南東    353.72    293.03
     南南東   382.88    280.69
       南     285.73    231.44
     南南西   478.79    263.83
      南西    555.44    322.14
     西南西   541.41    398.06
       西     586.19    480.00
     西北西   609.88    518.28
      北西    580.72    483.78
     北北西   673.67    428.17
    
[/code]


CC BY-SA 4.0
2020-01-25T02:00:16.293
62532
2020-01-25T13:49:07.527
2020-01-25T13:49:07.527
62513
answer


回答ありがとうございました。  
自分には難しく思うように動かせませんでした。

そこで今現在このような流れで動かしていこうかなと思っています。  
以下に記します。

* * *
[code]

    import csv
    import math
    
    cos0 = math.cos(math.radians(0))
    cos225 = math.cos(math.radians(22.5))
    cos45 = math.cos(math.radians(45))
    cos675 = math.cos(math.radians(67.5))
    
    f = open("test.csv", "r")
    reader = csv.reader(f)
    next(reader); next(reader); next(reader); next(reader); next(reader)
    
    Direction = ['南南西','南西','西南西','西','西北西','北西','北北西']
    
    sum = 0
    for row in reader:
      if not row[4].strip(): # 空行スキップ
        continue
      colE = float(row[4])
    
[/code]

* * *

この後に  
➀ colEを全て二乗

➁ Directionの７方位で  
方位が西のcolE(2乗したもの）にcos0を掛ける  
方位が西南西・西北西のcolE(2乗したもの）にcos225を掛ける  
方位が南西・北西のcolE(2乗したもの）にcos45を掛ける  
方位が南南西・北北西のcolE(2乗したもの）にcos675を掛ける

➂2乗値を補正した値を足し合わせる

といった流れでできないかと考えています。

ですが、特定の風向にそれぞれ補正をして、その補正した値をすべて足し合わせるといった処理が上手いことできません。  
どうかご回答お願い致します。


CC BY-SA 4.0
2020-01-27T02:42:30.793
62571
2020-01-27T02:42:30.793
37081
62513
answer