2019/05/12

エントリー中の画像表示

 過去のエントリーで、Markdown記法を使ったときにHatenaphotolifeにアップしている。画像が表示できないことがあり、記事の先頭と末尾では、同じリンク文字をいれても表示されることを確認している。バッククオートなどのコードを埋め込んだ間に画像をいれこもうとするとうまくいかないことがあり。もう一度Markdown記法の使い方についておさらいをしてみたが解決に至らなかった。  改めて、画像表示できなかった箇所の前後を確認したところスペースx4でCODE展開している後に指定したリンクが読めてないことが分かった。であればスペースx4を止めて```の囲み形式に変更したところ画像表示ができることを確認した。

CSVファイルを一気読みじゃなく行毎に処理していく

pythonCSV ライブラリを使う

とりあえず、1行毎に読み込む

import csv
with open('data.csv', newline='') as f:
    reader = csv.reader(f)
    i = 0
    for row in reader:
        print(i,row)
        i = i+1
0 ['ZXC system log format ver.1']
1 ['date 2019/05/01 00:00:01']
2 ['Format', 'x', 'y', 'color']
3 ['12', '8', '8', '1']
4 ['1', '2', '3', '4', '5', '6', '7', '8']
5 ['1', '2', '3', '4', '5', '6', '7', '8']
6 ['1', '2', '3', '4', '5', '6', '7', '8']
7 ['1', '2', '3', '4', '5', '6', '7', '8']
8 ['1', '2', '3', '4', '5', '6', '7', '8']
9 ['1', '2', '3', '4', '5', '6', '7', '8']
10 ['1', '2', '3', '4', '5', '6', '7', '8']
11 ['1', '2', '3', '4', '5', '6', '7', '8']
12 []
13 ['ZXC system log format ver.1']
14 ['date 2019/05/02 00:00:01']
15 ['Format', 'x', 'y', 'color']
16 ['12', '8', '8', '2']
17 ['8', '1', '2', '3', '4', '5', '6', '7']
18 ['8', '1', '2', '3', '4', '5', '6', '7']
19 ['8', '1', '2', '3', '4', '5', '6', '7']
20 ['8', '1', '2', '3', '4', '5', '6', '7']
21 ['8', '1', '2', '3', '4', '5', '6', '7']
22 ['8', '1', '2', '3', '4', '5', '6', '7']
23 ['8', '1', '2', '3', '4', '5', '6', '7']
24 ['8', '1', '2', '3', '4', '5', '6', '7']
25 []
26 ['ZXC system log format ver.1']
27 ['date 2019/05/03 00:00:01']
28 ['Format', 'x', 'y', 'color']
29 ['12', '8', '8', '3']
30 ['7', '8', '1', '2', '3', '4', '5', '6']
31 ['7', '8', '1', '2', '3', '4', '5', '6']
32 ['7', '8', '1', '2', '3', '4', '5', '6']
33 ['7', '8', '1', '2', '3', '4', '5', '6']
34 ['7', '8', '1', '2', '3', '4', '5', '6']
35 ['7', '8', '1', '2', '3', '4', '5', '6']
36 ['7', '8', '1', '2', '3', '4', '5', '6']
37 ['7', '8', '1', '2', '3', '4', '5', '6']
38 []
39 ['ZXC system log format ver.1']
40 ['date 2019/05/04 00:00:01']
41 ['Format', 'x', 'y', 'color']
42 ['12', '8', '8', '4']
43 ['6', '7', '8', '1', '2', '3', '4', '5']
44 ['6', '7', '8', '1', '2', '3', '4', '5']
45 ['6', '7', '8', '1', '2', '3', '4', '5']
46 ['6', '7', '8', '1', '2', '3', '4', '5']
47 ['6', '7', '8', '1', '2', '3', '4', '5']
48 ['6', '7', '8', '1', '2', '3', '4', '5']
49 ['6', '7', '8', '1', '2', '3', '4', '5']
50 ['6', '7', '8', '1', '2', '3', '4', '5']
51 []
52 ['ZXC system log format ver.1']
53 ['date 2019/05/05 00:00:01']
54 ['Format', 'x', 'y', 'color']
55 ['12', '8', '8', '5']
56 ['5', '6', '7', '8', '1', '2', '3', '4']
57 ['5', '6', '7', '8', '1', '2', '3', '4']
58 ['5', '6', '7', '8', '1', '2', '3', '4']
59 ['5', '6', '7', '8', '1', '2', '3', '4']
60 ['5', '6', '7', '8', '1', '2', '3', '4']
61 ['5', '6', '7', '8', '1', '2', '3', '4']
62 ['5', '6', '7', '8', '1', '2', '3', '4']
63 ['5', '6', '7', '8', '1', '2', '3', '4']
64 []
65 ['ZXC system log format ver.1']
66 ['date 2019/05/06 00:00:01']
67 ['Format', 'x', 'y', 'color']
68 ['12', '8', '8', '6']
69 ['4', '5', '6', '7', '8', '1', '2', '3']
70 ['4', '5', '6', '7', '8', '1', '2', '3']
71 ['4', '5', '6', '7', '8', '1', '2', '3']
72 ['4', '5', '6', '7', '8', '1', '2', '3']
73 ['4', '5', '6', '7', '8', '1', '2', '3']
74 ['4', '5', '6', '7', '8', '1', '2', '3']
75 ['4', '5', '6', '7', '8', '1', '2', '3']
76 ['4', '5', '6', '7', '8', '1', '2', '3']
77 []
78 ['ZXC system log format ver.1']
79 ['date 2019/05/07 00:00:01']
80 ['Format', 'x', 'y', 'color']
81 ['12', '8', '8', '7']
82 ['3', '4', '5', '6', '7', '8', '1', '2']
83 ['3', '4', '5', '6', '7', '8', '1', '2']
84 ['3', '4', '5', '6', '7', '8', '1', '2']
85 ['3', '4', '5', '6', '7', '8', '1', '2']
86 ['3', '4', '5', '6', '7', '8', '1', '2']
87 ['3', '4', '5', '6', '7', '8', '1', '2']
88 ['3', '4', '5', '6', '7', '8', '1', '2']
89 ['3', '4', '5', '6', '7', '8', '1', '2']
90 []
91 ['ZXC system log format ver.1']
92 ['date 2019/05/08 00:00:01']
93 ['Format', 'x', 'y', 'color']
94 ['12', '8', '8', '8']
95 ['2', '3', '4', '5', '6', '7', '8', '1']
96 ['2', '3', '4', '5', '6', '7', '8', '1']
97 ['2', '3', '4', '5', '6', '7', '8', '1']
98 ['2', '3', '4', '5', '6', '7', '8', '1']
99 ['2', '3', '4', '5', '6', '7', '8', '1']
100 ['2', '3', '4', '5', '6', '7', '8', '1']
101 ['2', '3', '4', '5', '6', '7', '8', '1']
102 ['2', '3', '4', '5', '6', '7', '8', '1']
103 []

読み込んだデータがすべて文字列になってしまうので個別にデコードする

import csv
with open('data.csv', newline='') as f:
    reader = csv.reader(f)
    i=1
    for row in reader:
        if len(row) == 0 :
            print(i,[])  # 改行だけのとき
        else:
            if row[0][0] in "-+0123456789" and row[0][1:].isnumeric() : # 数値の時
                print(i,[int(x_int) for x_int in row])
            else:
                try: # 小数点チェック
                        float(row[0])
                except ValueError: # NGの時は文字列
                    print(i,row)
                else:
                    print(i,[float(x) for x in row])
        i=i+1
1 ['ZXC system log format ver.1']
2 ['date 2019/05/01 00:00:01']
3 ['Format', 'x', 'y', 'color']
4 [1.01, 8.0, 8.0, 1.0]
5 [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
6 [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
7 [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
8 [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
9 [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
10 [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
11 [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
12 []
13 ['ZXC system log format ver.1']
14 ['date 2019/05/02 00:00:01']
15 ['Format', 'x', 'y', 'color']
16 [1.01, 8.0, 8.0, 2.0]
17 [8.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]
18 [8.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]
19 [8.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]
20 [8.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]
21 [8.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]
22 [8.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]
23 [8.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]
24 [8.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]
25 []
26 ['ZXC system log format ver.1']
27 ['date 2019/05/03 00:00:01']
28 ['Format', 'x', 'y', 'color']
29 [1.01, 8.0, 8.0, 3.0]
30 [7.0, 8.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
31 [7.0, 8.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
32 [7.0, 8.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
33 [7.0, 8.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
34 [7.0, 8.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
35 [7.0, 8.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
36 [7.0, 8.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
37 [7.0, 8.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
38 []
39 ['ZXC system log format ver.1']
40 ['date 2019/05/04 00:00:01']
41 ['Format', 'x', 'y', 'color']
42 [1.01, 8.0, 8.0, 4.0]
43 [6.0, 7.0, 8.0, 1.0, 2.0, 3.0, 4.0, 5.0]
44 [6.0, 7.0, 8.0, 1.0, 2.0, 3.0, 4.0, 5.0]
45 [6.0, 7.0, 8.0, 1.0, 2.0, 3.0, 4.0, 5.0]
46 [6.0, 7.0, 8.0, 1.0, 2.0, 3.0, 4.0, 5.0]
47 [6.0, 7.0, 8.0, 1.0, 2.0, 3.0, 4.0, 5.0]
48 [6.0, 7.0, 8.0, 1.0, 2.0, 3.0, 4.0, 5.0]
49 [6.0, 7.0, 8.0, 1.0, 2.0, 3.0, 4.0, 5.0]
50 [6.0, 7.0, 8.0, 1.0, 2.0, 3.0, 4.0, 5.0]
51 []
52 ['ZXC system log format ver.1']
53 ['date 2019/05/05 00:00:01']
54 ['Format', 'x', 'y', 'color']
55 [1.01, 8.0, 8.0, 5.0]
56 [5.0, 6.0, 7.0, 8.0, 1.0, 2.0, 3.0, 4.0]
57 [5.0, 6.0, 7.0, 8.0, 1.0, 2.0, 3.0, 4.0]
58 [5.0, 6.0, 7.0, 8.0, 1.0, 2.0, 3.0, 4.0]
59 [5.0, 6.0, 7.0, 8.0, 1.0, 2.0, 3.0, 4.0]
60 [5.0, 6.0, 7.0, 8.0, 1.0, 2.0, 3.0, 4.0]
61 [5.0, 6.0, 7.0, 8.0, 1.0, 2.0, 3.0, 4.0]
62 [5.0, 6.0, 7.0, 8.0, 1.0, 2.0, 3.0, 4.0]
63 [5.0, 6.0, 7.0, 8.0, 1.0, 2.0, 3.0, 4.0]
64 []
65 ['ZXC system log format ver.1']
66 ['date 2019/05/06 00:00:01']
67 ['Format', 'x', 'y', 'color']
68 [1.01, 8.0, 8.0, 6.0]
69 [4.0, 5.0, 6.0, 7.0, 8.0, 1.0, 2.0, 3.0]
70 [4.0, 5.0, 6.0, 7.0, 8.0, 1.0, 2.0, 3.0]
71 [4.0, 5.0, 6.0, 7.0, 8.0, 1.0, 2.0, 3.0]
72 [4.0, 5.0, 6.0, 7.0, 8.0, 1.0, 2.0, 3.0]
73 [4.0, 5.0, 6.0, 7.0, 8.0, 1.0, 2.0, 3.0]
74 [4.0, 5.0, 6.0, 7.0, 8.0, 1.0, 2.0, 3.0]
75 [4.0, 5.0, 6.0, 7.0, 8.0, 1.0, 2.0, 3.0]
76 [4.0, 5.0, 6.0, 7.0, 8.0, 1.0, 2.0, 3.0]
77 []
78 ['ZXC system log format ver.1']
79 ['date 2019/05/07 00:00:01']
80 ['Format', 'x', 'y', 'color']
81 [1.01, 8.0, 8.0, 7.0]
82 [3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 1.0, 2.0]
83 [3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 1.0, 2.0]
84 [3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 1.0, 2.0]
85 [3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 1.0, 2.0]
86 [3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 1.0, 2.0]
87 [3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 1.0, 2.0]
88 [3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 1.0, 2.0]
89 [3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 1.0, 2.0]
90 []
91 ['ZXC system log format ver.1']
92 ['date 2019/05/08 00:00:01']
93 ['Format', 'x', 'y', 'color']
94 [1.01, 8.0, 8.0, 8.0]
95 [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 1.0]
96 [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 1.0]
97 [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 1.0]
98 [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 1.0]
99 [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 1.0]
100 [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 1.0]
101 [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 1.0]
102 [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 1.0]
103 []

初めからデータ構造が分かっているなら個別にデコードことも可能

上記の例で作るとするとこんな感じ drive.google.com

tiffで行うとこんな感じ? read_tiff.py - Google ドライブ

CSV ファイル読み込み(pandas編)

CSV ファイル読み込み

pandasは、CSV仕様に沿って読み込んでいるみたいなので、EXCELでカンマ区切りで読み込めるファイルも読み込めないことがある

今回も、いろいろ調べるとCSV仕様がレコードは1つ以上の同じ個数のフィールドからなる。なんだって!である 最後のフィールドは、コンマで終わってはならない。これもなんてこったい!である
EXCELで表等を使って仕事をしたことがある人は分かると思うがROWの頭から最後までCOLUMがおなじですべて埋まっていることなんかあり得ない
特にあちこちのデータを集めてきて集計してグラフとか作るときはシート内を自由に使っているはずだ。これが何がまずいかというと
CSVをデコートするプログラムを書こうとすると1行目でデータ構造を確定してその後はカンマが来るたびに切り分けて分けていく処理をしたいという
至極当然な大昔のデータ処理的な感じである。ゆえに、今回読み込もうとした、メタデータフィールド、データーフィールド、メタデータフィールド、データーフィールドや、EXCELシートを開いてデータを張り付けて適当にグラフ化したシートをCSV出力するとformatエラーになる。第一にA1からデータを埋め込んでいない。第二に各セルに対して空白(NULL)が存在している。

(1)フィールドが空でありレコードの終わりまで続く場合は出力しないみたいな仕様のものは読み込んでくれない

f:id:chiyoh:20190505210533p:plain

import pandas as pd
df = pd.read_csv('data.csv')
print(df)
---------------------------------------------------------------------------

ParserError                               Traceback (most recent call last)

<ipython-input-1-d517e7bf72bb> in <module>
      1 import pandas as pd
----> 2 df = pd.read_csv('data.csv')
      3 print(df)


h:\Anaconda3\lib\site-packages\pandas\io\parsers.py in parser_f(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, squeeze, prefix, mangle_dupe_cols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, dayfirst, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, dialect, tupleize_cols, error_bad_lines, warn_bad_lines, delim_whitespace, low_memory, memory_map, float_precision)
    700                     skip_blank_lines=skip_blank_lines)
    701 
--> 702         return _read(filepath_or_buffer, kwds)
    703 
    704     parser_f.__name__ = name


h:\Anaconda3\lib\site-packages\pandas\io\parsers.py in _read(filepath_or_buffer, kwds)
    433 
    434     try:
--> 435         data = parser.read(nrows)
    436     finally:
    437         parser.close()


h:\Anaconda3\lib\site-packages\pandas\io\parsers.py in read(self, nrows)
   1137     def read(self, nrows=None):
   1138         nrows = _validate_integer('nrows', nrows)
-> 1139         ret = self._engine.read(nrows)
   1140 
   1141         # May alter columns / col_dict


h:\Anaconda3\lib\site-packages\pandas\io\parsers.py in read(self, nrows)
   1993     def read(self, nrows=None):
   1994         try:
-> 1995             data = self._reader.read(nrows)
   1996         except StopIteration:
   1997             if self._first_chunk:


pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader.read()


pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader._read_low_memory()


pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader._read_rows()


pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader._tokenize_rows()


pandas/_libs/parsers.pyx in pandas._libs.parsers.raise_parser_error()


ParserError: Error tokenizing data. C error: Expected 1 fields in line 3, saw 4

(2),(カンマ)がフィールドの最後にあっても問題なく読んでくれる

[f:id:chiyoh:20190505210536p:plain][f:id:chiyoh:20190505210749p:plain]

なんか、オプションを追加しないと読めなかったが、、、

import pandas as pd
df = pd.read_csv('ABC.csv',encoding="shift-jis")
print(df)
    装置別データの関係について                                         Unnamed: 1  \
0             NaN                                                NaN   
1             NaN                                                NaN   
2             NaN                                                NaN   
3             NaN                                                NaN   
4             NaN                                            入力パラメータ   
5             NaN                                                  0   
6             NaN                                                  1   
7             NaN                                                  2   
8             NaN                                                  3   
9             NaN                                                  4   
10            NaN                                                  5   
11            NaN                                                  6   
12            NaN                                                  7   
13            NaN                                                NaN   
14            NaN  結果:装置Cはリミットを超えているのでパラメータ5以上では使用できない。逆に装置Bは最大値に...   
15            NaN                                                NaN   
16            NaN                                                NaN   
17            NaN                                                NaN   
18            NaN                                                NaN   
19            NaN                                                NaN   

   Unnamed: 2 Unnamed: 3 Unnamed: 4  
0         NaN        NaN        NaN  
1         NaN        NaN        NaN  
2         NaN        NaN        NaN  
3         NaN        NaN        NaN  
4         装置A        装置B        装置C  
5      0.5023     0.2323     0.0023  
6      2.3423     1.6023     3.3423  
7      6.6823     2.9723    10.6823  
8     13.0223     4.3423    22.0223  
9     21.3623     5.7123    37.3623  
10    31.7023     7.0823    56.7023  
11    44.0423     8.4523    80.0423  
12    58.3823     9.8223   107.3823  
13        NaN        NaN        NaN  
14        NaN        NaN        NaN  
15        NaN        NaN        NaN  
16        NaN        NaN        NaN  
17        NaN        NaN        NaN  
18        NaN        NaN        NaN  
19        NaN        NaN        NaN  

強引に読み込む方法を見つけた

import pandas as pd
dat = pd.read_csv('data.csv', names=("A","B","C","D","E","F","G","H","I","J"),header=None)
print(dat)
                              A    B    C      D    E    F    G    H   I   J
0   ZXC system log format ver.1  NaN  NaN    NaN  NaN  NaN  NaN  NaN NaN NaN
1      date 2019/05/01 00:00:01  NaN  NaN    NaN  NaN  NaN  NaN  NaN NaN NaN
2                        Format    x    y  color  NaN  NaN  NaN  NaN NaN NaN
3                            12    8    8      1  NaN  NaN  NaN  NaN NaN NaN
4                             1    2    3      4  5.0  6.0  7.0  8.0 NaN NaN
5                             1    2    3      4  5.0  6.0  7.0  8.0 NaN NaN
6                             1    2    3      4  5.0  6.0  7.0  8.0 NaN NaN
7                             1    2    3      4  5.0  6.0  7.0  8.0 NaN NaN
8                             1    2    3      4  5.0  6.0  7.0  8.0 NaN NaN
9                             1    2    3      4  5.0  6.0  7.0  8.0 NaN NaN
10                            1    2    3      4  5.0  6.0  7.0  8.0 NaN NaN
11                            1    2    3      4  5.0  6.0  7.0  8.0 NaN NaN
12  ZXC system log format ver.1  NaN  NaN    NaN  NaN  NaN  NaN  NaN NaN NaN
13     date 2019/05/02 00:00:01  NaN  NaN    NaN  NaN  NaN  NaN  NaN NaN NaN
14                       Format    x    y  color  NaN  NaN  NaN  NaN NaN NaN
15                           12    8    8      2  NaN  NaN  NaN  NaN NaN NaN
16                            8    1    2      3  4.0  5.0  6.0  7.0 NaN NaN
17                            8    1    2      3  4.0  5.0  6.0  7.0 NaN NaN
18                            8    1    2      3  4.0  5.0  6.0  7.0 NaN NaN
19                            8    1    2      3  4.0  5.0  6.0  7.0 NaN NaN
20                            8    1    2      3  4.0  5.0  6.0  7.0 NaN NaN
21                            8    1    2      3  4.0  5.0  6.0  7.0 NaN NaN
22                            8    1    2      3  4.0  5.0  6.0  7.0 NaN NaN
23                            8    1    2      3  4.0  5.0  6.0  7.0 NaN NaN
24  ZXC system log format ver.1  NaN  NaN    NaN  NaN  NaN  NaN  NaN NaN NaN
25     date 2019/05/03 00:00:01  NaN  NaN    NaN  NaN  NaN  NaN  NaN NaN NaN
26                       Format    x    y  color  NaN  NaN  NaN  NaN NaN NaN
27                           12    8    8      3  NaN  NaN  NaN  NaN NaN NaN
28                            7    8    1      2  3.0  4.0  5.0  6.0 NaN NaN
29                            7    8    1      2  3.0  4.0  5.0  6.0 NaN NaN
..                          ...  ...  ...    ...  ...  ...  ...  ...  ..  ..
66                            4    5    6      7  8.0  1.0  2.0  3.0 NaN NaN
67                            4    5    6      7  8.0  1.0  2.0  3.0 NaN NaN
68                            4    5    6      7  8.0  1.0  2.0  3.0 NaN NaN
69                            4    5    6      7  8.0  1.0  2.0  3.0 NaN NaN
70                            4    5    6      7  8.0  1.0  2.0  3.0 NaN NaN
71                            4    5    6      7  8.0  1.0  2.0  3.0 NaN NaN
72  ZXC system log format ver.1  NaN  NaN    NaN  NaN  NaN  NaN  NaN NaN NaN
73     date 2019/05/07 00:00:01  NaN  NaN    NaN  NaN  NaN  NaN  NaN NaN NaN
74                       Format    x    y  color  NaN  NaN  NaN  NaN NaN NaN
75                           12    8    8      7  NaN  NaN  NaN  NaN NaN NaN
76                            3    4    5      6  7.0  8.0  1.0  2.0 NaN NaN
77                            3    4    5      6  7.0  8.0  1.0  2.0 NaN NaN
78                            3    4    5      6  7.0  8.0  1.0  2.0 NaN NaN
79                            3    4    5      6  7.0  8.0  1.0  2.0 NaN NaN
80                            3    4    5      6  7.0  8.0  1.0  2.0 NaN NaN
81                            3    4    5      6  7.0  8.0  1.0  2.0 NaN NaN
82                            3    4    5      6  7.0  8.0  1.0  2.0 NaN NaN
83                            3    4    5      6  7.0  8.0  1.0  2.0 NaN NaN
84  ZXC system log format ver.1  NaN  NaN    NaN  NaN  NaN  NaN  NaN NaN NaN
85     date 2019/05/08 00:00:01  NaN  NaN    NaN  NaN  NaN  NaN  NaN NaN NaN
86                       Format    x    y  color  NaN  NaN  NaN  NaN NaN NaN
87                           12    8    8      8  NaN  NaN  NaN  NaN NaN NaN
88                            2    3    4      5  6.0  7.0  8.0  1.0 NaN NaN
89                            2    3    4      5  6.0  7.0  8.0  1.0 NaN NaN
90                            2    3    4      5  6.0  7.0  8.0  1.0 NaN NaN
91                            2    3    4      5  6.0  7.0  8.0  1.0 NaN NaN
92                            2    3    4      5  6.0  7.0  8.0  1.0 NaN NaN
93                            2    3    4      5  6.0  7.0  8.0  1.0 NaN NaN
94                            2    3    4      5  6.0  7.0  8.0  1.0 NaN NaN
95                            2    3    4      5  6.0  7.0  8.0  1.0 NaN NaN

[96 rows x 10 columns]

結局のところ、読み込めるのは固定rows,columnsのみで1行目をみてcolumn数を固定してしまうのでそれより後ろのレコードでフィールド数が多いとErrorになってしまう。だったら初めからcolumn数を指定してやればよいというだけの話。なんだかなぁ

f:id:chiyoh:20190505210536p:plainf:id:chiyoh:20190505210749p:plain

うちのマシンは、int64じゃない!?

numpyのデータタイプ

これから、Numpyを使っていろいろと演算等を行うにあたって自分が何をやっているのか知っておく必要がある
つまり、π(パイ)はいくつなんだ?という話なのである。(実際は、いくつとしてデータに記録されるのかという話)

事の始まり

import numpy as np
def ndarray_info(np_array):
    print("配列の軸数(次元) = ",np_array.ndim)
    print("各次元の配列のサイズ = ",np_array.shape)
    print("要素の総数 = ",np_array.size)
    print("要素の形式 = ",np_array.dtype)
    print("1要素のbyte数 = ",np_array.itemsize)

print("-- a --")
a = np.array([1,2,3])
ndarray_info(a)
print("-- b --")
b = np.array([1.2,2.3,3.4])
ndarray_info(b)
-- a --
配列の軸数(次元) =  1
各次元の配列のサイズ =  (3,)
要素の総数 =  3
要素の形式 =  int32
1要素のbyte数 =  4
-- b --
配列の軸数(次元) =  1
各次元の配列のサイズ =  (3,)
要素の総数 =  3
要素の形式 =  float64
1要素のbyte数 =  8

うぅ?
あれ、、、、、要素の形式 = int32 ってなんでint64じゃないの?

import sys
print("Python version =",sys.version)
print("Python platform =",sys.platform)
print("Python intger=",sys.int_info)
print("Python float =",sys.float_info)
Python version = 3.7.3 (default, Mar 27 2019, 17:13:21) [MSC v.1915 64 bit (AMD64)]
Python platform = win32
Python intger= sys.int_info(bits_per_digit=30, sizeof_digit=4)
Python float = sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)

Python自体は、タスクマネージャーを見る限り64bitプログラムとして動ている。プラットフォームがwin32なのが気になるが。
intは、4byteで32bitなのね。floatは、8byteで64bitみたいだ。min_10_exp=-307, dig=15, mant_dig=53が、倍精度浮動小数点数とちょっと違うが表現の違いだけなのだろう。
で、Numpyはどうなのか?

import numpy as np
print("np.float => ",np.finfo(np.float))
print("np.float_ => ",np.finfo(np.float_))
print("np.float32 => ",np.finfo(np.float32))
print("np.float64 => ",np.finfo(np.float64))
print("np.single => ",np.finfo(np.single))
print("np.double => ",np.finfo(np.double))
print("np.longdouble => ",np.finfo(np.longdouble))
print("float => ",np.finfo(float))  # floatは、OKみたいだ
np.float =>  Machine parameters for float64
---------------------------------------------------------------
precision =  15   resolution = 1.0000000000000001e-15
machep =    -52   eps =        2.2204460492503131e-16
negep =     -53   epsneg =     1.1102230246251565e-16
minexp =  -1022   tiny =       2.2250738585072014e-308
maxexp =   1024   max =        1.7976931348623157e+308
nexp =       11   min =        -max
---------------------------------------------------------------

np.float_ =>  Machine parameters for float64
---------------------------------------------------------------
precision =  15   resolution = 1.0000000000000001e-15
machep =    -52   eps =        2.2204460492503131e-16
negep =     -53   epsneg =     1.1102230246251565e-16
minexp =  -1022   tiny =       2.2250738585072014e-308
maxexp =   1024   max =        1.7976931348623157e+308
nexp =       11   min =        -max
---------------------------------------------------------------

np.float32 =>  Machine parameters for float32
---------------------------------------------------------------
precision =   6   resolution = 1.0000000e-06
machep =    -23   eps =        1.1920929e-07
negep =     -24   epsneg =     5.9604645e-08
minexp =   -126   tiny =       1.1754944e-38
maxexp =    128   max =        3.4028235e+38
nexp =        8   min =        -max
---------------------------------------------------------------

np.float64 =>  Machine parameters for float64
---------------------------------------------------------------
precision =  15   resolution = 1.0000000000000001e-15
machep =    -52   eps =        2.2204460492503131e-16
negep =     -53   epsneg =     1.1102230246251565e-16
minexp =  -1022   tiny =       2.2250738585072014e-308
maxexp =   1024   max =        1.7976931348623157e+308
nexp =       11   min =        -max
---------------------------------------------------------------

np.single =>  Machine parameters for float32
---------------------------------------------------------------
precision =   6   resolution = 1.0000000e-06
machep =    -23   eps =        1.1920929e-07
negep =     -24   epsneg =     5.9604645e-08
minexp =   -126   tiny =       1.1754944e-38
maxexp =    128   max =        3.4028235e+38
nexp =        8   min =        -max
---------------------------------------------------------------

np.double =>  Machine parameters for float64
---------------------------------------------------------------
precision =  15   resolution = 1.0000000000000001e-15
machep =    -52   eps =        2.2204460492503131e-16
negep =     -53   epsneg =     1.1102230246251565e-16
minexp =  -1022   tiny =       2.2250738585072014e-308
maxexp =   1024   max =        1.7976931348623157e+308
nexp =       11   min =        -max
---------------------------------------------------------------

np.longdouble =>  Machine parameters for float64
---------------------------------------------------------------
precision =  15   resolution = 1.0000000000000001e-15
machep =    -52   eps =        2.2204460492503131e-16
negep =     -53   epsneg =     1.1102230246251565e-16
minexp =  -1022   tiny =       2.2250738585072014e-308
maxexp =   1024   max =        1.7976931348623157e+308
nexp =       11   min =        -max
---------------------------------------------------------------

float =>  Machine parameters for float64
---------------------------------------------------------------
precision =  15   resolution = 1.0000000000000001e-15
machep =    -52   eps =        2.2204460492503131e-16
negep =     -53   epsneg =     1.1102230246251565e-16
minexp =  -1022   tiny =       2.2250738585072014e-308
maxexp =   1024   max =        1.7976931348623157e+308
nexp =       11   min =        -max
---------------------------------------------------------------

このプラットフォームが扱えるNumpyの浮動小数点は、float32(single)float64(double)の2種類か
floatはfloat64と置き換えられるみたいだ

import numpy as np
print("np.int => ",np.iinfo(np.int))
print("np.byte => ",np.iinfo(np.byte))
print("np.ubyte => ",np.iinfo(np.ubyte))
print("np.short => ",np.iinfo(np.short))
print("np.ushort => ",np.iinfo(np.ushort))
print("np.intc => ",np.iinfo(np.intc))   # C言語ライブラリのint
print("np.uintc => ",np.iinfo(np.uintc)) # C言語ライブラリのuint
print("np.int_ => ",np.iinfo(np.int_))
print("np.uint => ",np.iinfo(np.uint))
print("np.longlong => ",np.iinfo(np.longlong))
print("np.ulonglong => ",np.iinfo(np.ulonglong))
print("int => ",np.iinfo(int))  # intは、OKみたいだ
np.int =>  Machine parameters for int32
---------------------------------------------------------------
min = -2147483648
max = 2147483647
---------------------------------------------------------------

np.byte =>  Machine parameters for int8
---------------------------------------------------------------
min = -128
max = 127
---------------------------------------------------------------

np.ubyte =>  Machine parameters for uint8
---------------------------------------------------------------
min = 0
max = 255
---------------------------------------------------------------

np.short =>  Machine parameters for int16
---------------------------------------------------------------
min = -32768
max = 32767
---------------------------------------------------------------

np.ushort =>  Machine parameters for uint16
---------------------------------------------------------------
min = 0
max = 65535
---------------------------------------------------------------

np.intc =>  Machine parameters for int32
---------------------------------------------------------------
min = -2147483648
max = 2147483647
---------------------------------------------------------------

np.uintc =>  Machine parameters for uint32
---------------------------------------------------------------
min = 0
max = 4294967295
---------------------------------------------------------------

np.int_ =>  Machine parameters for int32
---------------------------------------------------------------
min = -2147483648
max = 2147483647
---------------------------------------------------------------

np.uint =>  Machine parameters for uint32
---------------------------------------------------------------
min = 0
max = 4294967295
---------------------------------------------------------------

np.longlong =>  Machine parameters for int64
---------------------------------------------------------------
min = -9223372036854775808
max = 9223372036854775807
---------------------------------------------------------------

np.ulonglong =>  Machine parameters for uint64
---------------------------------------------------------------
min = 0
max = 18446744073709551615
---------------------------------------------------------------

int =>  Machine parameters for int32
---------------------------------------------------------------
min = -2147483648
max = 2147483647
---------------------------------------------------------------

このプラットフォームが扱えるNumpyの整数は、8,16,32,64bit長の符号有り無しみたいだintはint32と置き換えられる
(この、マシン環境ではintはint64にならないMPUが古いから?)

まとめ

Numpyで使用されているデフォルトの形式を理解しておく必要がある。LinuxWindowsまたはMPUの違いにより基礎となるC演算ライブラリ等が変わってくるからである。同じプログラムソースでもnp.array(raw)で作られる内部データ形式(dtype)がint32,int64やfloat32,float64と違う場合があるので演算結果に相違が出てくる場合がある。掛け算の掛け算とか総和を求める関数とかオーバーフローを起こしたり丸目誤差問題が発生したりなどである。最近のMPUであればint64,float64になっているので大きな数字を扱えるのでほとんど気にしないのかな?

(SSE関係は実装されているがAVX関係は実装されてないんだよなぁこのMPUだからなのかなぁ?普通にWindows 10なんだけど) 追記:stackoverflowに、同様の質問がありその結果は、LinuxMacOSは、int64になっているがWindowsはint32だということ。 int_ Default integer type (same as C long; normally either int64 or int32) とのことで、windowsが定義しているC言語ライブラリがlongがint32でたのOSはlongはint64なのでそうなっているとのこと うちのマシンが古すぎるせい!ってわけでなくよかったよ。

蛇足

import numpy as np
pi_str = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679"
pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
pi2 = 31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
print("python π = ",pi_str,type(pi_str))

print("=== Python(Myマシン) ===")
print("python π = ", pi,type(pi))
print("python 101桁pi2 = ",pi2,type(pi2))
pi3 = pi2 +1
print("python 101桁pi2 +1 = ",pi3,type(pi3))
piar = [pi]
piar2 = [pi2]
print("python array piar[0] = ", piar[0],type(piar[0]))
print("python array piar2[0] = ", piar2[0],type(piar2[0]))

print("=== Numpy float(Myマシン) ===")
nppi = np.empty((1))
nppi[0] = pi
print("np.array(π) = ",nppi,nppi.dtype)
nppi_f64 = np.empty((1),dtype=np.float64)
nppi_f64[0] = pi
print("np.array(π,dtype=np.float64) = ", nppi_f64,nppi_f64.dtype)
nppi_f32 = np.empty((1),dtype=np.float32)
nppi_f32[0] = pi
print("np.array(π,dtype=np.float32) = ", nppi_f32,nppi_f32.dtype)
nppi_f16 = np.empty((1),dtype=np.float16)
nppi_f16[0] = pi
print("np.array(π,dtype=np.float16) = ", nppi_f16,nppi_f16.dtype)
nppi_i = nppi.astype(np.int64)
print("np.array(π).astype(np.int64) 整数化 = ",nppi_i,nppi_i.dtype)


print("=== Numpy integer(Myマシン) ===")
nppi2 = np.array(piar2)
print("np.array(101桁整数) = ",nppi2,nppi2.dtype)
nppi_i32 = np.array(piar2,dtype=np.int32)
print("nppi_i32 = ",nppi_i32,nppi_i32.dtype)
python π =  3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679 <class 'str'>
=== Python(Myマシン) ===
python π =  3.141592653589793 <class 'float'>
python 101桁pi2 =  31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679 <class 'int'>
python 101桁pi2 +1 =  31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170680 <class 'int'>
python array piar[0] =  3.141592653589793 <class 'float'>
python array piar2[0] =  31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679 <class 'int'>
=== Numpy float(Myマシン) ===
np.array(π) =  [3.14159265] float64
np.array(π,dtype=np.float64) =  [3.14159265] float64
np.array(π,dtype=np.float32) =  [3.1415927] float32
np.array(π,dtype=np.float16) =  [3.14] float16
np.array(π).astype(np.int64) 整数化 =  [3] int64
=== Numpy integer(Myマシン) ===
np.array(101桁整数) =  [31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679] object



---------------------------------------------------------------------------

OverflowError                             Traceback (most recent call last)

<ipython-input-5-0da0a4edd8c4> in <module>
     35 nppi2 = np.array(piar2)
     36 print("np.array(101桁整数) = ",nppi2,nppi2.dtype)
---> 37 nppi_i32 = np.array(piar2,dtype=np.int32)
     38 print("nppi_i32 = ",nppi_i32,nppi_i32.dtype)


OverflowError: Python int too large to convert to C long
import numpy as np
import math
def int_info(dt):
    dt_max = np.iinfo(dt).max
    a = math.log10(dt_max)
    print(dt,"max値 = ",dt_max,"(",int(a),"桁)")

int_info(np.int)
int_info(np.int8)
int_info(np.int16)
int_info(np.int32)
int_info(np.int64)
int_info(np.uint8)
int_info(np.uint16)
int_info(np.uint32)
int_info(np.uint64)
<class 'int'> max値 =  2147483647 ( 9 桁)
<class 'numpy.int8'> max値 =  127 ( 2 桁)
<class 'numpy.int16'> max値 =  32767 ( 4 桁)
<class 'numpy.int32'> max値 =  2147483647 ( 9 桁)
<class 'numpy.int64'> max値 =  9223372036854775807 ( 18 桁)
<class 'numpy.uint8'> max値 =  255 ( 2 桁)
<class 'numpy.uint16'> max値 =  65535 ( 4 桁)
<class 'numpy.uint32'> max値 =  4294967295 ( 9 桁)
<class 'numpy.uint64'> max値 =  18446744073709551615 ( 19 桁)

パイソンに桁数は無いという話はあったが、整数の話であったか。小数点は、15桁まで表示している
対して、Numpyは、float64がpythonより少ない8桁何か変。float32は、7桁。float64float32で1桁の差しかないのはおかしい。float16int化はお約束ということで
Numpyの整数は、dtype=Noneの場合はなんかもう数値じゃなくオブジェクトとして扱っているし。int32はErrorなのね。有効桁数しらべたけどそんな感じなのね

と思ったが!調べていくと

import numpy as np
pi_str = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679"
pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
pi2 = 31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
print("python π(文字列)    = ",pi_str)

print("=== Python(Myマシン) float ===")
print("python π(有効桁)    = ", pi)
print("python π            = ","%.100f" % pi)
piar = [pi]
print("python array(有効桁) = ", piar[0])
print("python array         = ","%.100f" % piar[0])

print("=== Numpy float(Myマシン) ===")
nppi = np.empty((1))
nppi[0] = pi
nppi_f64 = np.empty((1),dtype=np.float64)
nppi_f64[0] = pi
nppi_f32 = np.empty((1),dtype=np.float32)
nppi_f32[0] = pi
nppi_f16 = np.empty((1),dtype=np.float16)
nppi_f16[0] = pi

print("str    π            = ",pi_str)
print("flot   π            = ", nppi[0])
print("flot   π(100桁表示) = ","%.100f" % nppi[0])
print("flot64 π            = ", nppi_f64[0])
print("flot64 π(100桁表示) = ","%.100f" % nppi_f64[0])
print("flot32 π            = ",nppi_f32[0])
print("flot32 π(100桁表示) = ","%.100f" % nppi_f32[0])
print("flot16 π      = ",nppi_f16[0])
print("flot16 π(100桁表示) = ","%.100f" % nppi_f16[0])
python π(文字列)    =  3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
=== Python(Myマシン) float ===
python π(有効桁)    =  3.141592653589793
python π            =  3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000
python array(有効桁) =  3.141592653589793
python array         =  3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000
=== Numpy float(Myマシン) ===
str    π            =  3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
flot   π            =  3.141592653589793
flot   π(100桁表示) =  3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000
flot64 π            =  3.141592653589793
flot64 π(100桁表示) =  3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000
flot32 π            =  3.1415927
flot32 π(100桁表示) =  3.1415927410125732421875000000000000000000000000000000000000000000000000000000000000000000000000000000
flot16 π      =  3.14
flot16 π(100桁表示) =  3.1406250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

print表記の切り上げだったみたいです。pythonのデータ型とNumpyのデータ型ではprint表記の有効桁数が違うみたいでその影響みたいです
float64表現では、pythonとnumpyで同じ桁数のデータを保存していることがわかりました。

PIL(pillow)画像をnumpyにしたり戻したり

画像オブジェクトをnumpy配列に変換

import numpy as np
from PIL import Image
im = Image.open('sample20x15.bmp')
im

f:id:chiyoh:20190504145157p:plain

im_paltte = im.quantize() # パレットカラー 1chカラー
im_CMYK = im.convert('CMYK') # CMYK 4chカラー
im_grey = im.convert('L') # グレースケール 1chカラー
im_bw = im.convert('1') # 白黒 1chカラー
im_i = im.convert('I') # どのように変換されるかわからんが int型に変換
im_f = im.convert('F') #  どのように変換されるかわからんが float型に変換

print("--RGB--")
print("画像モード = ",im.mode)
print("省略")
print("--paltte--")
print("画像モード = ",im_paltte.mode)
print("省略")
print("--CMYK--")
print("画像モード = ",im_CMYK.mode)
print("画像サイズ(x,y) = ",im_CMYK.size)
print("pixel格納形式 = ",im_CMYK.getbands())
print("pixel(0,0) = ",im_CMYK.getpixel((0,0)))
print("pixel(0,0)の形式 = ",type(im_CMYK.getpixel((0,0))))
print("各チャンネルの形式 = ",type(im_CMYK.getpixel((0,0))[0]),type(im_CMYK.getpixel((0,0))[1]),
      type(im_CMYK.getpixel((0,0))[2]),type(im_CMYK.getpixel((0,0))[3]))
print("--grey--")
print("画像モード = ",im_grey.mode)
print("画像サイズ(x,y) = ",im_grey.size)
print("pixel格納形式 = ",im_grey.getbands())
print("pixel(0,0) = ",im_grey.getpixel((0,0)))
print("pixel(0,0)の形式 = ",type(im_grey.getpixel((0,0))))
print("各チャンネルの形式 = ",type(im_grey.getpixel((0,0)))) # 1chなのでそのまま
print("--binary--")
print("画像モード = ",im_bw.mode)
print("画像サイズ(x,y) = ",im_bw.size)
print("pixel格納形式 = ",im_bw.getbands())
print("pixel(0,0) = ",im_bw.getpixel((0,0)))
print("pixel(0,0)の形式 = ",type(im_bw.getpixel((0,0))))
print("各チャンネルの形式 = ",type(im_bw.getpixel((0,0)))) # 1chなのでそのまま
print("--int--")
print("画像モード = ",im_i.mode)
print("省略")
print("--float--")
print("画像モード = ",im_f.mode)
print("省略")
--RGB--
画像モード =  RGB
省略
--paltte--
画像モード =  P
省略
--CMYK--
画像モード =  CMYK
画像サイズ(x,y) =  (20, 15)
pixel格納形式 =  ('C', 'M', 'Y', 'K')
pixel(0,0) =  (55, 219, 76, 0)
pixel(0,0)の形式 =  <class 'tuple'>
各チャンネルの形式 =  <class 'int'> <class 'int'> <class 'int'> <class 'int'>
--grey--
画像モード =  L
画像サイズ(x,y) =  (20, 15)
pixel格納形式 =  ('L',)
pixel(0,0) =  101
pixel(0,0)の形式 =  <class 'int'>
各チャンネルの形式 =  <class 'int'>
--binary--
画像モード =  1
画像サイズ(x,y) =  (20, 15)
pixel格納形式 =  ('1',)
pixel(0,0) =  0
pixel(0,0)の形式 =  <class 'int'>
各チャンネルの形式 =  <class 'int'>
--int--
画像モード =  I
省略
--float--
画像モード =  F
省略

読み込んだ画像RGBオブジェクトを各モードの画像に変換した。いままで見てなかったCMYKとLグレスケと1白黒については内部データも確認しておく

numpy配列に変換

dat_RGB = np.asarray(im)
dat_paltte = np.asarray(im_paltte)
dat_CMYK = np.asarray(im_CMYK)
dat_grey = np.asarray(im_grey)
dat_bw = np.asarray(im_bw)
dat_i = np.asarray(im_i)
dat_f = np.asarray(im_f)
dat_paltte += dat_paltte/2
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-4-d0f6116c4334> in <module>
----> 1 dat_paltte += dat_paltte/2


ValueError: output array is read-only

書き換えNGのようだ

dat_paltte.flags
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : False
  WRITEABLE : False
  ALIGNED : True
  WRITEBACKIFCOPY : False
  UPDATEIFCOPY : False
dat_paltte.flags.writeable = True
dat_paltte += dat_paltte/2
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-6-612dcc4be249> in <module>
----> 1 dat_paltte.flags.writeable = True
      2 dat_paltte += dat_paltte/2


ValueError: cannot set WRITEABLE flag to True of this array

なるほど、np.asarray()で変換した配列は参照ようなのね
np.array()を使って変換すると

dat2_paltte = np.array(im_paltte)
dat2_paltte.flags
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  WRITEBACKIFCOPY : False
  UPDATEIFCOPY : False

np.asarray()で変換すると配列書き換え不可、np.array()で行えば書き換え可能
だけど大体numpyの場合演算すると新しいオブジェクト生成されてしまうのでnp.asarray()で変換して速度優先にするって感じか

numpy配列に変換した中身

print("--RGB--")
print("オブジェクト型 = ",type(dat_RGB))
print("配列要素 = ",dat_RGB.dtype)
print("配列形 = ",dat_RGB.shape)
print("配列要素サイズ = ",dat_RGB.size)
print("シリーズに並べた時の隣軸との距離(Y軸,X軸,ch間) = ",dat_RGB.strides)
print("次元数 = ",dat_RGB.ndim)
print("1つの配列要素の長さ(バイト単位) = ",dat_RGB.itemsize)
print("使用されている総バイト数 = ",dat_RGB.nbytes)
print("メモリレイアウト情報 = ",dat_RGB.flags)
--RGB--
オブジェクト型 =  <class 'numpy.ndarray'>
配列要素 =  uint8
配列形 =  (15, 20, 3)
配列要素サイズ =  900
シリーズに並べた時の隣軸との距離(Y軸,X軸,ch間) =  (60, 3, 1)
次元数 =  3
1つの配列要素の長さ(バイト単位) =  1
使用されている総バイト数 =  900
メモリレイアウト情報 =    C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : False
  WRITEABLE : False
  ALIGNED : True
  WRITEBACKIFCOPY : False
  UPDATEIFCOPY : False

基本のRGBを見るとRGBの各チャンネルに1軸を使っていて、3次元配列になっているのね

print("ベースになるオブジェクト = ",dat_RGB.base)
print("len(base) = ",len(dat_RGB.base))
print("配列の先頭のオブジェクト = ",dat_RGB.data)
print("type(data) = ",type(dat_RGB.data))
print("len(data) = ",len(dat_RGB.data))
ベースになるオブジェクト =  b"\xc8$\xb3\xc5%\xb5\xc0%\xb6\xbc%\xb7\xb8&\xb9\xb3&\xbb\xad'\xbc\xa9(\xbe\xa4(\xbf\x9e)\xc2\x99)\xc4\x94*\xc5\x8e+\xc7\x89+\xc9\x84,\xcb~,\xccx-\xcfs.\xd0n.\xd2h.\xd4\xc5$\xb4\xc1$\xb6\xbd%\xb7\xb8&\xb9\xb3'\xba\xae'\xbb\xa9(\xbe\xa4(\xbf\x9f(\xc1\x9a)\xc3\x94*\xc5\x90*\xc7\x8a+\xc8\x85+\xca\x7f,\xcdz-\xcet-\xd0n.\xd2i/\xd4c/\xd6\xc2$\xb5\xbe%\xb6\xb9&\xb8\xb5&\xba\xaf'\xbc\xaa(\xbd\xa6(\xbf\xa1(\xc1\x9c)\xc2\x96*\xc4\x90+\xc6\x8b+\xc8\x86+\xca\x80,\xcc{-\xceu-\xd0p.\xd1j.\xd4e/\xd5_0\xd7\xbe%\xb6\xba%\xb8\xb5&\xba\xb1'\xbb\xac'\xbc\xa7'\xbf\xa2)\xc0\x9c)\xc2\x97*\xc4\x91*\xc6\x8c*\xc8\x86+\xca\x81,\xcc|,\xcdv-\xcfq.\xd2k.\xd3f/\xd5a0\xd7\\0\xd8\xbb%\xb8\xb6&\xba\xb2'\xbb\xac'\xbd\xa8'\xbe\xa3(\xc0\x9d(\xc2\x98)\xc3\x92*\xc5\x8e+\xc7\x87+\xc9\x83,\xcb}-\xcdw.\xcfr-\xd0l.\xd3h/\xd5a0\xd6]1\xd8W1\xda\xb7&\xb9\xb3'\xbb\xad&\xbc\xa9'\xbe\xa4(\xc0\x9e(\xc1\x99*\xc3\x93*\xc5\x8f*\xc7\x89+\xc9\x83,\xcb~,\xccy-\xcfs.\xd0n/\xd2h.\xd4b/\xd6^0\xd7X0\xd9S1\xdb\xb4&\xba\xaf'\xbc\xaa'\xbe\xa4(\xbf\xa0)\xc2\x9a)\xc3\x95*\xc5\x8f+\xc6\x8a+\xc9\x85,\xca\x7f,\xccz-\xcet-\xd0o.\xd2j/\xd3d/\xd5_0\xd7Y0\xdaT1\xdbO2\xdd\xb0'\xbb\xab'\xbd\xa5'\xbf\xa0)\xc0\x9c)\xc2\x96)\xc4\x90*\xc6\x8c*\xc8\x85+\xca\x80,\xcc{-\xceu-\xcfp.\xd1k/\xd3e0\xd5_0\xd7[0\xd9U1\xdaP1\xddK2\xde\xab'\xbd\xa6(\xbf\xa2(\xc0\x9d)\xc2\x97)\xc4\x92*\xc6\x8c+\xc8\x87+\xc9\x82,\xcc|,\xcdw-\xd0q.\xd1l/\xd3f/\xd5a0\xd7\\1\xd9W1\xdaQ2\xdcL2\xdeG3\xdf\xa8(\xbe\xa3)\xc0\x9e)\xc2\x99)\xc4\x92*\xc6\x8d+\xc8\x88+\xc9\x82,\xcb},\xcdx-\xcfr-\xd0m.\xd3g/\xd4b/\xd6]0\xd8X1\xd9R1\xdcM2\xddH2\xdfC3\xe1\xa4(\xbf\x9e(\xc1\x99*\xc3\x94*\xc6\x8f+\xc6\x89+\xc9\x84,\xca\x7f,\xcdy-\xces.\xd0n.\xd2h/\xd4c/\xd6^0\xd8X0\xd9S2\xdbN2\xddI2\xdfD3\xe0?3\xe3\x9f(\xc1\x9a)\xc3\x95*\xc5\x90+\xc7\x8b*\xc9\x85+\xca\x7f,\xccz-\xceu.\xd0o.\xd2j.\xd4d/\xd6_0\xd7Z0\xd9T1\xdbO2\xdcJ2\xdfE2\xe0A3\xe2<4\xe3\x9c)\xc2\x96*\xc4\x91*\xc6\x8c+\xc8\x86+\xca\x81,\xcc{-\xceu-\xcfq.\xd2j/\xd3f/\xd5`0\xd7Z1\xd8U1\xdaP2\xdcK2\xdeF3\xe0B3\xe1=4\xe384\xe5\x97)\xc4\x92*\xc6\x8d+\xc7\x87,\xca\x81,\xcb|-\xcdw-\xcfq.\xd1k/\xd3f/\xd5a/\xd7\\0\xd8V1\xdbR1\xdcL2\xdeG2\xdfB3\xe1>4\xe394\xe455\xe5\x93*\xc5\x8e+\xc7\x89,\xc9\x82,\xca},\xcdx-\xcer.\xd0m.\xd2h/\xd4b/\xd6]0\xd8X0\xdaR1\xdcN1\xddI2\xdfC3\xe1?3\xe3;4\xe465\xe615\xe6"
len(base) =  900
配列の先頭のオブジェクト =  <memory at 0x000001AEDC7E67C8>
type(data) =  <class 'memoryview'>
len(data) =  15

なるほど、baseはim.tobytes()な感じかな。dataは列要素に入っている行要素が15という感じで行要素にはch要素の3があるって感じなのかな。

各要素にアクセス

print("pixel(0,0) = ",im.getpixel((0,0)))
print("numpy配列(0,0) = ",dat_RGB[0,0])
print("pixel(1,0) = ",im.getpixel((1,0)))
print("numpy配列(1,0) = ",dat_RGB[1,0])
print("numpy配列(0,1) = ",dat_RGB[0,1])
print("numpy配列(0,1,:) = ",dat_RGB[0,1,:])
print("numpy配列(0,1)R = ",dat_RGB[0,1,0])
print("numpy配列(0,1)G = ",dat_RGB[0,1,1])
print("numpy配列(0,1)B = ",dat_RGB[0,1,2])
print("numpy配列(Y軸=0) = ",dat_RGB[0])
pixel(0,0) =  (200, 36, 179)
numpy配列(0,0) =  [200  36 179]
pixel(1,0) =  (197, 37, 181)
numpy配列(1,0) =  [197  36 180]
numpy配列(0,1) =  [197  37 181]
numpy配列(0,1,:) =  [197  37 181]
numpy配列(0,1)R =  197
numpy配列(0,1)G =  37
numpy配列(0,1)B =  181
numpy配列(Y軸=0) =  [[200  36 179]
 [197  37 181]
 [192  37 182]
 [188  37 183]
 [184  38 185]
 [179  38 187]
 [173  39 188]
 [169  40 190]
 [164  40 191]
 [158  41 194]
 [153  41 196]
 [148  42 197]
 [142  43 199]
 [137  43 201]
 [132  44 203]
 [126  44 204]
 [120  45 207]
 [115  46 208]
 [110  46 210]
 [104  46 212]]

PILでは、(x,y)のタプルで表現していたがnumpy配列に変換すると[y,x,ch]の順番になる。x,yの順番が逆なので注意
[y,x]と表現すれば[R G B]の3要素が表現できる。[0]1次元表記すると(X軸とch)の要素すべてが表現できるのね

1チャンネルのパレットカラーの場合はどうか?

print("--paltte--")
print("オブジェクト型 = ",type(dat_paltte))
print("配列要素 = ",dat_paltte.dtype)
print("配列形 = ",dat_paltte.shape)
print("配列要素サイズ = ",dat_paltte.size)
print("シリーズに並べた時の隣軸との距離(Y軸,X軸,ch間) = ",dat_paltte.strides)
print("次元数 = ",dat_paltte.ndim)
print("1つの配列要素の長さ(バイト単位) = ",dat_paltte.itemsize)
print("使用されている総バイト数 = ",dat_paltte.nbytes)
print("メモリレイアウト情報 = ",dat_paltte.flags)
--paltte--
オブジェクト型 =  <class 'numpy.ndarray'>
配列要素 =  uint8
配列形 =  (15, 20)
配列要素サイズ =  300
シリーズに並べた時の隣軸との距離(Y軸,X軸,ch間) =  (20, 1)
次元数 =  2
1つの配列要素の長さ(バイト単位) =  1
使用されている総バイト数 =  300
メモリレイアウト情報 =    C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : False
  WRITEABLE : False
  ALIGNED : True
  WRITEBACKIFCOPY : False
  UPDATEIFCOPY : False

その他の画像

def print_np_type(dat):
    print("配列要素 = ",dat.dtype)
    print("次元数 = ",dat.ndim)
    print("配列形 = ",dat.shape)
    print("配列要素サイズ = ",dat.size)

print("--CMYK--")
print_np_type(dat_CMYK)
print("--gray--")
print_np_type(dat_grey)
print("--白黒--")
print_np_type(dat_bw)
print("--int--")
print_np_type(dat_i)
print("--float--")
print_np_type(dat_f)
--CMYK--
配列要素 =  uint8
次元数 =  3
配列形 =  (15, 20, 4)
配列要素サイズ =  1200
--gray--
配列要素 =  uint8
次元数 =  2
配列形 =  (15, 20)
配列要素サイズ =  300
--白黒--
配列要素 =  bool
次元数 =  2
配列形 =  (15, 20)
配列要素サイズ =  300
--int--
配列要素 =  int32
次元数 =  2
配列形 =  (15, 20)
配列要素サイズ =  300
--float--
配列要素 =  float32
次元数 =  2
配列形 =  (15, 20)
配列要素サイズ =  300

なるほど、色要素としてチャンネルがあるものは3次元、無いのは縦横の2次元
要素タイプは種別ごとに違う感じか

numpy配列からPIL(pillow)オブジェクトに

im = Image.frombytes()でなく、Image.fromarray()のほうがいろいろとケアしてくれるみたいです 配列情報からサイズや画像モードなんかを読み取ってくれるみたいです

im2_RGB = Image.fromarray(dat_RGB)
im2_paltte = Image.fromarray(dat_paltte)
im2_CMYK = Image.fromarray(dat_CMYK)
im2_grey = Image.fromarray(dat_grey)
im2_bw = Image.fromarray(dat_bw)
im2_i = Image.fromarray(dat_i)
im2_f = Image.fromarray(dat_f)

def print_image_type(im):
    print("画像モード = ",im.mode)
    print("画像サイズ(x,y) = ",im.size)
    print("pixel格納形式 = ",im.getbands())
    print("pixel(0,0) = ",im.getpixel((0,0)))
    print("pixel(0,0)の形式 = ",type(im.getpixel((0,0))))

def print_image_type2(im):
    print_image_type(im)
    print("pixel要素形式 = ",type(im.getpixel((0,0))[0]))
    
print("--RGB--")
print_image_type2(im2_RGB)
print("--CMYK--")
print_image_type2(im2_CMYK)
print("--パレット--")
print_image_type(im2_paltte)
print("--グレスケ--")
print_image_type(im2_grey)
print("--白黒--")
print_image_type(im2_bw)
print("--int--")
print_image_type(im2_i)
print("--float--")
print_image_type(im2_f)
--RGB--
画像モード =  RGB
画像サイズ(x,y) =  (20, 15)
pixel格納形式 =  ('R', 'G', 'B')
pixel(0,0) =  (200, 36, 179)
pixel(0,0)の形式 =  <class 'tuple'>
pixel要素形式 =  <class 'int'>
--CMYK--
画像モード =  RGBA
画像サイズ(x,y) =  (20, 15)
pixel格納形式 =  ('R', 'G', 'B', 'A')
pixel(0,0) =  (55, 219, 76, 0)
pixel(0,0)の形式 =  <class 'tuple'>
pixel要素形式 =  <class 'int'>
--パレット--
画像モード =  L
画像サイズ(x,y) =  (20, 15)
pixel格納形式 =  ('L',)
pixel(0,0) =  0
pixel(0,0)の形式 =  <class 'int'>
--グレスケ--
画像モード =  L
画像サイズ(x,y) =  (20, 15)
pixel格納形式 =  ('L',)
pixel(0,0) =  101
pixel(0,0)の形式 =  <class 'int'>
--白黒--
画像モード =  1
画像サイズ(x,y) =  (20, 15)
pixel格納形式 =  ('1',)
pixel(0,0) =  0
pixel(0,0)の形式 =  <class 'int'>
--int--
画像モード =  I
画像サイズ(x,y) =  (20, 15)
pixel格納形式 =  ('I',)
pixel(0,0) =  101
pixel(0,0)の形式 =  <class 'int'>
--float--
画像モード =  F
画像サイズ(x,y) =  (20, 15)
pixel格納形式 =  ('F',)
pixel(0,0) =  101.33799743652344
pixel(0,0)の形式 =  <class 'float'>

結果は、'P'と'L','CMYK'と'RGBA'が元に戻らない感じですね
チャンネルの数と要素タイプで区別しているみたいです

チャンネル 1 タイプ boolが '1'
チャンネル 1 タイプ uint8が 'L'
チャンネル 1 タイプ intが 'I'
チャンネル 1 タイプ floatが 'F'
チャンネル 3 タイプ uint8が 'RGB'
チャンネル 4 タイプ uint8が 'RGBA'
に自動変換でしょうか

Image.fromarray(obj, mode=None)なのでパラメータでモードを指定すれば問題無し

im3_paltte = Image.fromarray(dat_paltte,'P')
im3_CMYK = Image.fromarray(dat_CMYK,'CMYK')

print("--パレット--")
print_image_type(im3_paltte)
print("--CMYK--")
print_image_type2(im3_CMYK)
--パレット--
画像モード =  P
画像サイズ(x,y) =  (20, 15)
pixel格納形式 =  ('P',)
pixel(0,0) =  0
pixel(0,0)の形式 =  <class 'int'>
--CMYK--
画像モード =  CMYK
画像サイズ(x,y) =  (20, 15)
pixel格納形式 =  ('C', 'M', 'Y', 'K')
pixel(0,0) =  (55, 219, 76, 0)
pixel(0,0)の形式 =  <class 'tuple'>
pixel要素形式 =  <class 'int'>

パレットカラーモードについて

dat_paltte = np.asarray(im_paltte)で配列に変換してもこれだけではIndexカラー番号のみが変換されて
色情報がありません。パレットカラーを取り扱う必要があります
data=im.getpalette()im.putpalette(data)でパレットの情報の出し入れが出来る
パレット情報はリスト形式の[R0,G0,B0,R1,G1,B1, ... R255,G255,B255]なので(R+G+B)*256 = 768要素になる

pc_list = im_paltte.getpalette()
print("形式 = ",type(pc_list))
print("要素数 = ",len(pc_list))
print("要素数形式 = ",type(pc_list[0]))
形式 =  <class 'list'>
要素数 =  768
要素数形式 =  <class 'int'>

pythonが通常扱えるリストで、整数形式の768要素になっている。numpy配列にする

pc_array = np.array(im_paltte.getpalette())
print_np_type(pc_array)
print("頭から16要素 = ",pc_array[0:16])
print("--画像っぽくRGBを分ける--")
pc_array2 = pc_array.reshape((256,3))
print_np_type(pc_array2)
print("インデックス番号5の色 = ",pc_array2[5])
配列要素 =  int32
次元数 =  1
配列形 =  (768,)
配列要素サイズ =  768
頭から16要素 =  [200  36 179 197  37 181 197  36 180 194  36 181 193  36 182 192]
--画像っぽくRGBを分ける--
配列要素 =  int32
次元数 =  2
配列形 =  (256, 3)
配列要素サイズ =  768
インデックス番号5の色 =  [192  37 182]

reshapeすれば扱いやすくなる。例えばインデックスカラーの1番を黒にするとかカラーオブジェクトを使っていろいろできるかも

pc_array2[1]= (0,0,0) #インデックス2を黒に
pc_list = pc_array2.tolist()
print("頭から8 = ",pc_list[0:8])
pc_list2 = pc_array2.flatten().tolist()
print("頭から8 = ",pc_list2[0:8])
頭から8 =  [[200, 36, 179], [0, 0, 0], [197, 36, 180], [194, 36, 181], [193, 36, 182], [192, 37, 182], [190, 37, 182], [189, 37, 183]]
頭から8 =  [200, 36, 179, 0, 0, 0, 197, 36]

numpy配列にしたものも、flatten()tolist()を使えば768要素の1次元配列にリストに戻せるので
その後im.putpalette(data)すればよい f:id:chiyoh:20190504145157p:plain

PIL(pillow)画像をPython配列に変換してみる

画像オブジェクトを配列に変換

画像読み込み

from PIL import Image
im = Image.open('sample20x15.bmp')
im

f:id:chiyoh:20190504095104p:plain

PIL画像データ配列構造

左上を原点とするXY座標(Xは、右側に進む。Yは下側に進む)とすると横書きのノートのように上から左から右に端まで行ったら次の行まで行きY=0から1にしてX=0に戻りまた左から右にというデータ配列でデータをImage.tobytes()Image.frombytes(mode, size, dataでデータのやり取りができる

data = im.tobytes()
print("データの種類 = ",type(data))
print("データの長さ = ",len(data))
print("データの単位 = ",type(data[0]))
print("画像モード = ",im.mode)
print("幅、高さ、チャンネル数 = ",im.size[0],im.size[1],len(im.getpixel((0,0))))
print("幅x高さxチャンネル数 = ",im.size[0]*im.size[1]*len(im.getpixel((0,0))))
データの種類 =  <class 'bytes'>
データの長さ =  900
データの単位 =  <class 'int'>
画像モード =  RGB
幅、高さ、チャンネル数 =  20 15 3
幅x高さxチャンネル数 =  900

RGBからBGRの並びに変えてみる

data2 = bytearray()
for xy in range(im.size[0]*im.size[1]):
    data2 += bytearray( (data[3*xy+2],data[3*xy+1],data[3*xy]))
print("RGB(0,0) = ",list(data[0:3]))
print("BGR(0,0) = ",list(data2[0:3]))
RGB(0,0) =  [200, 36, 179]
BGR(0,0) =  [179, 36, 200]

byte配列の並びが変換できた

im1 = Image.frombytes('RGB',(20,15),data)
im1

f:id:chiyoh:20190504095100p:plain

バイト列から画像オブジェクトに戻った

im2 = Image.frombytes('RGB',(20,15),bytes(data2))
im2

f:id:chiyoh:20190504095058p:plain

R⇔B入れ替えたデータで画像オブジェクトにした

def getBytes2pixel(im,xy):
    x,y = xy
    w,h = im.size
    dat = im.tobytes()
    print(xy," = ",dat[3*(w*y+x)],dat[3*(w*y+x)+1],dat[3*(w*y+x)+2])

print("--im1--")
getBytes2pixel(im1,(0,0))
getBytes2pixel(im1,(19,14))
print("--im2--")
getBytes2pixel(im2,(0,0))
getBytes2pixel(im2,(19,14))
--im1--
(0, 0)  =  200 36 179
(19, 14)  =  49 53 230
--im2--
(0, 0)  =  179 36 200
(19, 14)  =  230 53 49

pythonのbytes,bytearrayを使って画像オブジェクトは作成できる

listとも互換なので普通の配列として使える。ただし、byte単位なので0~255のRGBや、L(グレー)やP(パレット)でしかできない? I(32int)やF(32float)の場合どうなる?

I(32int)やF(32float)の場合

import struct
im_i32 = Image.new('I',(20,15))
im_i32.putpixel((0,0),1)  # (0,0) =1
im_i32.putpixel((2,0),-1)  # (2,0) = -1 符号表記
print("mode = ",im_i32.mode)
print("size = ",im_i32.size)
print("getbands = ",im_i32.getbands())
print("pixel(0,0) = ",im_i32.getpixel((0,0)))
print("pixel(0,0) = ",type(im_i32.getpixel((0,0))))
data_i32 = im_i32.tobytes()
print("データの種類 = ",type(data_i32))
print("データの長さ = ",len(data_i32))
print("データの単位 = ",type(data_i32[0]))
print("データ始めの16bytes = ",data_i32[0:16].hex())
print("int32にデコード = ", struct.unpack('iiii',data_i32[0:16]))
mode =  I
size =  (20, 15)
getbands =  ('I',)
pixel(0,0) =  1
pixel(0,0) =  <class 'int'>
データの種類 =  <class 'bytes'>
データの長さ =  1200
データの単位 =  <class 'int'>
データ始めの16bytes =  0100000000000000ffffffff00000000
int32にデコード =  (1, 0, -1, 0)
im_f32 = Image.new('F',(20,15))
im_f32.putpixel((0,0),1)  # (0,0) =1
im_f32.putpixel((2,0),-1)  # (2,0) = -1 符号表記
im_f32.putpixel((3,0),0.003)  # (3,0) = 0.003 小数点
im_f32.putpixel((4,0),1.234e5)  # (4,0) = 1.234e5 指数表示
print("mode = ",im_f32.mode)
print("size = ",im_f32.size)
print("getbands = ",im_f32.getbands())
print("pixel(0,0) = ",im_f32.getpixel((0,0)))
print("pixel(0,0) = ",type(im_f32.getpixel((0,0))))
data_f32 = im_f32.tobytes()
print("データの種類 = ",type(data_f32))
print("データの長さ = ",len(data_f32))
print("データの単位 = ",type(data_f32[0]))
print("データ始めの32bytes = ",data_f32[0:32].hex())
print("float32にデコード = ", struct.unpack('ffffffff',data_f32[0:32]))
mode =  F
size =  (20, 15)
getbands =  ('F',)
pixel(0,0) =  1.0
pixel(0,0) =  <class 'float'>
データの種類 =  <class 'bytes'>
データの長さ =  1200
データの単位 =  <class 'int'>
データ始めの32bytes =  0000803f00000000000080bfa69b443b0004f147000000000000000000000000
float32にデコード =  (1.0, 0.0, -1.0, 0.003000000026077032, 123400.0, 0.0, 0.0, 0.0)

WxHx(CHx32bit/8bit)20*15*1*32/8=1200 でIもFも1200bytesなのね。
並び順序は他と同じでピクセルデータがint32とfloatになっているということね
デコードして普通の配列にして処理かけてstruct.packかければもとに戻せるかな 

おさらいで内部表現しらべた

64bit長のデータって改めてみると実に大きいのね。大きいといえば天文単位
天文単位1auは、149,597,870,700 mみたいだけど64bit長じゃないとメートル換算できないのか
GPSシステムとかの細かい計算とかに使うのかな?

32bit整数(int,uint)
符号付き -2,147,483,648 ~ 2,147,483,647
符号なし 0 ~ 4,294,967,295

64bit整数(long,ulong)
符号付き -9,223,372,036,854,775,808 から 9,223,372,036,854,775,807
符号なし 0 ~ 18,446,744,073,709,551,615

32bit浮動小数点値(float) 単精度浮動小数点数
64bit浮動小数点値(double) 倍精度浮動小数点数
128bit浮動小数点値(decimal) 四倍精度浮動小数点数