Python | Numpy > fileIO > 同じ形式のファイルの平均を取る | 一つだけ形式の異なるファイルに対応

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
```

## 同じ形式のファイルの平均を取る

### 処理概要

```txt:mueller(一部)
theta s11 s12 s13 s14 s21 s22 s23 s24 s31 s32 s33 s34 s41 s42 s43 s44
0.00 1.4154797779E+02 0.0000000000E+00 0.0000000000E+00 2.0774468080E-11 0.0000000000E+00 1.4154797779E+02 1.5202490767E-10 0.0000000000E+00 0.0000000000E+00 -1.5202490767E-10 1.4154797779E+02 0.0000000000E+00 2.0774468080E-11 0.0000000000E+00 0.0000000000E+00 1.4154797779E+02
1.00 1.4140075324E+02 -5.8903789321E-03 1.0170761154E-11 2.4386238017E-11 -5.8903789321E-03 1.4140075324E+02 1.4176203701E-10 -3.5948816258E-12 1.0178382783E-11 -1.4176220755E-10 1.4140075276E+02 9.9513428708E-03 2.4385372022E-11 3.6038425530E-12 -9.9513428708E-03 1.4140075276E+02
2.00 1.4095992060E+02 -2.3466973506E-02 2.0327789144E-11 2.8007664918E-11 -2.3466973506E-02 1.4095992060E+02 1.3134304986E-10 -7.1547834934E-12 2.0357543715E-11 -1.3134441652E-10 1.4095991305E+02 3.9706966470E-02 2.8000740778E-11 7.1871195463E-12 -3.9706966470E-02 1.4095991305E+02
3.00 1.4022799573E+02 -5.2447620268E-02 3.0438949100E-11 3.1616176968E-11 -5.2447620268E-02 1.4022799573E+02 1.2079755856E-10 -1.0660883463E-11 3.0504182908E-11 -1.2080217069E-10 1.4022795770E+02 8.8972728682E-02 3.1592843704E-11 1.0725708703E-11 -8.8972728682E-02 1.4022795770E+02
4.00 1.3920914771E+02 -9.2366899825E-02 4.0475376063E-11 3.5192981027E-11 -9.2366899825E-02 1.3920914771E+02 1.1015915993E-10 -1.4090607479E-11 4.0588197313E-11 -1.1017007824E-10 1.3920902824E+02 1.5726195578E-01 3.5137810177E-11 1.4191725769E-11 -1.5726195578E-01 1.3920902824E+02
```

上記のようなファイルが実行パラメータごとに生成される。
それらすべてのファイルの平均を取りたい。
Numpyを使う。
備考:１行目はテキストなので、処理の対象外にしている。

### code

```test_readfile_180114.py
import numpy as np

IN_FILE = 'mueller'

# 1. check number of rows
dat = np.genfromtxt(IN_FILE, skip_header=1)
SIZE_ROW = len(dat)

# 2. initialization
cnt = 0
wrk = [[0.0] for idx in range(SIZE_ROW)]

# 3. average
for loop in range(2):
    dat = np.genfromtxt(IN_FILE, skip_header=1)
    wrk += dat
    cnt += 1
wrk /= cnt

print(dat)

print(np.array_equal(wrk, dat))

```

```txt:run
$ python3 test_readfile_180114.py 
[[  0.00000000e+00   1.41547978e+02   0.00000000e+00 ...,   0.00000000e+00
    0.00000000e+00   1.41547978e+02]
 [  1.00000000e+00   1.41400753e+02  -5.89037893e-03 ...,   3.60384255e-12
   -9.95134287e-03   1.41400753e+02]
 [  2.00000000e+00   1.40959921e+02  -2.34669735e-02 ...,   7.18711955e-12
   -3.97069665e-02   1.40959913e+02]
 ..., 
 [  1.78000000e+02   2.90454298e+00   1.06470426e-02 ...,   3.09882878e-12
    8.30494719e-03  -2.90451159e+00]
 [  1.79000000e+02   2.91191096e+00   2.66669488e-03 ...,   1.54438853e-12
    2.08133542e-03  -2.91190900e+00]
 [  1.80000000e+02   2.91437449e+00   2.22044605e-15 ...,  -2.68787383e-18
    9.99200722e-16  -2.91437449e+00]]
True
```

今回の例では同じファイルを複数回読み、平均を取った結果がnumpy.array_equal()でTrueになっている（正常)。
`flist = glob.glob("run*/mueller")`でイテレータを作れば複数ファイルの平均になるでしょう。


### 関連

- [python > array > 個数を決めて初期化する > mylist = [idx for idx in range(10)] / mylist = [0 for idx in range(10)] >> mylist = [0] * 10](https://qiita.com/7of9/items/586f62fa46dc3409d954)
    - コメントにおいて初期化方法色々教えていただいています
- [numpy.array_equal](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.array_equal.html)

## 一つのファイルだけ異なる形式の対応

### 処理の変更

30個のファイルのうち、１つだけ行数が異なるファイルが見つかった。
先頭の181行の平均を使うため、インデキシングでの制限を追加してみた。
( `wrk += dat[:SIZE_ROW]`の部分 )

### codeと実行

```py:CODE_171216_Euler/average_Mueller_180114.py
import numpy as np
import glob

'''
v0.1 Jan. 14, 2018
  - average for files for Row=(181 and 361)
'''

IN_FILE = 'mueller'

# 1. set number of rows
SIZE_ROW = 181

# 2. initialization
cnt = 0
wrk = [[0.0] for idx in range(SIZE_ROW)]

# 3. average
for elem in glob.glob("run*/" + IN_FILE):
    print(elem)
    dat = np.genfromtxt(elem, skip_header=1)
    wrk += dat[:SIZE_ROW]
    cnt += 1
wrk /= cnt

print(wrk)

```

```txt:run
python3 CODE_171216_Euler/average_Mueller_180114.py
...
run42504_sphere_g16_m1.5/mueller
run42520_sphere_g16_m1.5/mueller
run42522_sphere_g16_m1.5/mueller
run42512_sphere_g16_m1.5/mueller
[[  0.00000000e+00   1.41266663e+02   8.50460126e-02 ...,   5.03161654e-02
    1.05674362e-01   1.41262323e+02]
 [  1.00000000e+00   1.41119789e+02   8.43144017e-02 ...,   4.60682864e-02
    9.21477970e-02   1.41115441e+02]
 [  2.00000000e+00   1.40678630e+02   7.34507557e-02 ...,   4.16923910e-02
    5.64094037e-02   1.40674262e+02]
 ..., 
 [  1.78000000e+02   2.93669137e+00   1.93028734e-02 ...,  -4.30890938e-03
   -1.47490584e-02  -2.93435403e+00]
 [  1.79000000e+02   2.94413753e+00   1.07732314e-02 ...,  -3.97841341e-03
   -2.10551291e-02  -2.94182555e+00]
 [  1.80000000e+02   2.94622219e+00   7.89386791e-03 ...,  -3.64095328e-03
   -2.32492180e-02  -2.94392174e+00]]
```

最後の行の1つめの項目が180.0になっていることで、平均自体の正常動作は確認した。