Python文字列で書かれた行列・配列を数値に変換したい(jsonの読み方も含む)
正直いい方法がないか教えてくださいって感じです。
問題の全貌:なんでテキストで行列保存するねん。
jsonファイルとか最近読み込まなきゃいけない時があるのですが,そこからちゃんとデータを読み出すの大変じゃない?
ってお話です。
"[1.1,2.2]"っていう文字列から配列に起こすのが面倒というので
jsonファイル読み出し
例えば次のようなjsonファイルがあったとします。
{ total: "15", page: "1", records: "15", rows : [ {cell:"[1, 1]"}, {cell:"[2, "2]"}, {cell:"[15, 15]"}, ] }
読み出しはpythonで
import json with open('data.json') as data_file: data = json.load(data_file)
以下のように書かないのは用がないなら開いたらすぐ閉じるべきという思想があるのでしょう。
f = open('data.json', 'r') jsonData = json.load(f)
該当データへのアクセス
基本的には,
total: "15", ...となっていたら
a = data[total]
とすればaに "15"が格納されるという仕組みです。
階層構造になっている場合はdata[hoge][fuga][]...とつなげていきます。
また,カッコが{でなくて[になっている場合は配列ですので
b = data[rows][0][cell]
とうてばbに"[1, 1]"が格納されます。
はいではこれをどうしましょうという話です。
python文字列から数値へのキャスト
単一の数字なら簡単です。int()やfloat()に文字列をぶち込むだけです。
文字を並べたときのキャスト
"1.1,2.2"ときた場合はこう上手くは生きません。
そういうのはcsvにしてくれよ…。
numpyを使うと楽になるとか。
>>> np.fromstring('\x01\x02', dtype=np.uint8) array([1, 2], dtype=uint8) >>> np.fromstring('1 2', dtype=int, sep=' ') array([1, 2]) >>> np.fromstring('1, 2', dtype=int, sep=',') array([1, 2]) >>> np.fromstring('\x01\x02\x03\x04\x05', dtype=np.uint8, count=3) array([1, 2, 3], dtype=uint8)
解決策(Not smart)
しかしてこの解決策は以下のようになる...のかなぁ
Python 2.7 convert 2d string array to float array - Stack Overflow
あとはnumpyから配列へと変換をしちゃえばっと。
解決策(Not smart)
astとjsonをロードしたあわせ技があります。短いですが欠点はevalを使っていること。
stackoverflowでも非難されていました。
numpy.array(ast.literal_eval(', '.join(data.split(' '))))
convert string representation of array to numpy array in python - Stack Overflow
多分これで動くけど私は結局ヒューマンデコードしましたよね。(クソ)(技術の敗北)(人間はかしこいのです)
関連して
似たような問題も知っておくとイライラを防げそうです。
python - Convert string to numpy array - Stack Overflow