

### 前提・実現したいこと

以下のような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乗する。

➁次に角度補正を行いたいため、風向によって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
        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-27T09:28:36.093
62582
2020-05-05T11:03:00.287
37081
question
python
python csv処理


**本回答は見当外れの回答でした。**  
元の回答の`エラーその1`と`エラーその2`はエラーとはなりません。

質問の`以下のようなcsvファイル`を`以下のcsvファイル`と誤解していました。

`,`区切りであれば`for row in reader:`の`row`は項目のリストであるため、サイズ`len(row)`は1ではありません。

以下は元の回答です。

* * *

該当のソースコードを実行してみましたが、エラーが発生し、`#この先からつまずいています。`まで達していませんでした。

**エラーその1**

[code]

    if not row[4].strip(): # 空行スキップ
    
[/code]

rowはサイズが1のリストでした。`row[4]`でエラーになります。  
単純に空行をスキップするなら以下のコードでよいと思います。

[code]

    if not row: # 空行スキップ
    
[/code]

* * *

**エラーその2**

[code]

    colE = float(row[4])
    
[/code]

エラーその1と同じ理由でエラーとなりました。  
空白かタブコード(複数)でカラムに分割するのであれば以下のコードでできると思います。

[code]

    import re
    row = re.split('[ \t]+', row[0])
    colE = float(row[4])
    
[/code]

**その他**  
単なる転記ミスかもしれませんが、5カラム目と方角の区切りが全角空白のものがありました。

> 2016 12 23 7 10.6 東  
>  2016 12 23 8 10.4 北東  
>  2016 12 23 9 10.5 西  
>  ↑ ここが全角空白


CC BY-SA 4.0
2020-01-27T13:44:25.173
62586
2020-01-28T00:27:36.267
2020-01-28T00:27:36.267
35558
35558
62582
answer


なるべく質問記事のソースコードに変更を加えない方向で対応すると以下のようになるでしょう。  
@akira ejiri さん指摘のcsvデータ中の全角空白は半角空白に修正したとします。

  * 風速を2乗するのは ** 2 を使います
  * 風向に応じた値については、風向リストに対応する係数値のリストを用意し、合致する風向文字列のインデックスを取得して、係数値リストの同じインデックス位置からデータを持ってくる方法を取ります
  * 上記を全部計算後に合計するのではなく、その都度加算していきます

修正・追加した行およびその付近に、その内容をコメントで記述しています。

[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")
    # 以下の行でcsvの区切り記号を空白文字へ変更し、さらに余計な空白をスキップ
    reader = csv.reader(f, delimiter=' ', skipinitialspace=True)
    next(reader); next(reader); next(reader); next(reader); next(reader)
    
    Direction = ['南南西',  '南西','西南西',    '西','西北西',  '北西','北北西']
    # 上記Directionに対応する係数データのリスト
    DFactor   = [  cos675,   cos45,  cos225,    cos0,  cos225,   cos45,  cos675]
    
    sum = 0.0 # 浮動小数点なので 0.0 で初期化
    for row in reader:
        if (not row[4]) or (not row[5]): # 風速or風向データの無い行をスキップ
            continue
        if not row[5] in Direction: # Directionに含まれない風速・風向データはスキップ
            continue
        colE = float(row[4])
        # 風速の2乗×風向対応係数値を合計に加算する
        sum += (colE ** 2) * DFactor[Direction.index(row[5])]
    
    print(sum) # 合計値の表示、必要ならば小数点以下 x桁までなどと調整する
    
[/code]


CC BY-SA 4.0
2020-01-27T15:13:01.787
62590
2020-01-27T15:13:01.787
26370
62582
answer


以下のようなcsvファイルを～として分かりにくい表現を使ってしまっていました。  
実際のファイルを張り付けたり、上手に伝えるべきでした。

回答者の方のコードを参考にして、実際のcsvファイルを動かしてみたところ  
list index out of rangeとエラーがでてしまい

[code]

        if (not row[4]) or (not row[5]): # 風速or風向データの無い行をスキップ
    
[/code]

この部分で止まってしまいました。

以前までの似たような処理をする際に使用していたコードと比べながら

* * *
[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("羽茂23.csv", "r")
    reader = csv.reader(f)
    next(reader); next(reader); next(reader); next(reader); next(reader)
    
    Direction = ['南南西','南西','西南西','西','西北西','北西','北北西']
    # 上記Directionに対応する係数データのリスト
    DFactor   = [cos675,cos45,cos225,cos0,cos225,cos45,cos675]
    
    sum = 0.0 # 浮動小数点なので 0.0 で初期化
    for row in reader:
        if not row[4].strip(): # 空行スキップ
            continue
        if not row[5] in Direction: # Directionに含まれない風速・風向データはスキップ
             continue
        colE = float(row[4])
        # 風速の2乗×風向対応係数値を合計に加算する
        sum += (colE ** 2) * DFactor[Direction.index(row[5])]
    
    print(sum) # 合計値の表示、必要ならば小数点以下 x桁までなどと調整する
    
[/code]

* * *

と少し変更したところ動きました。

私が載せた「以下のようなcsvデータ」が良くなかったことが原因でした。  
すいません。

上に記したコードでは動きました。  
お手数をおかけして申し訳ありません。  
回答、コメントしてくださった方々ありがとうございます。


CC BY-SA 4.0
2020-01-28T08:29:33.317
62606
2020-01-28T08:29:33.317
37081
62582
answer