amazon

4.2.13

python numpy array to structured array

まず、np.array (ndarrayのfield値を持っていないもの)を作ってみる。
>>> # How to make a structured array from non-field array
...
>>>
>>> import numpy as np
>>> x = np.array([(1,2,'a'),(3,4,'b')])
>>> x
array([['1', '2', 'a'],
    ['3', '4', 'b']],
   dtype='|S1')
>>>

このxを次のようなstructured arrayに変換したい。

>>> # From this x I wanted to make a structred array like this.
...
>>> y
array([(1, 2, 'a'), (3, 4, 'b')],
   dtype=[('name1', '|u1'), ('name2', '<i4'), ('name3', '|S20')])
>>>

まず、直接np.arrayに入れてみる。

>>> # Try converting directly x to a structrued array,
...
>>> y0 = np.array(x, dtype=[('name1','u1'), ('name2', 'i4'), ('name3', 'S20')])Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'a'
>>> # It failed.
...

失敗する。
次にxをリストにして渡してみる。

>>> # Try another way,
...
>>> y1 = np.array(x.tolist(), dtype=[('name1','u1'), ('name2', 'i4'), ('name3', 'S20')])
>>> y1
array([[(49, 0, ''), (50, 0, ''), (97, 0, '')],
    [(51, 0, ''), (52, 0, ''), (98, 0, '')]],
   dtype=[('name1', '|u1'), ('name2', '<i4'), ('name3', '|S20')])
>>>
>>> # This is not what I wanted.
...
>>>

エラーは出ないが、作りたかったものと異なる。

ところで、np.arrayで渡す配列は次のようにタプルとリストが混在していても認識してくれる。

>>> # Usually np.array doesn't care what input array is, like below.
...
>>>
>>> np.array([[2,3,4],[2,5,6]])
array([[2, 3, 4],
    [2, 5, 6]])
>>>
>>> np.array([(2,3,4),(2,5,6)])
array([[2, 3, 4],
    [2, 5, 6]])
>>>
>>> np.array(((2,3,4),(2,5,6)))
array([[2, 3, 4],
    [2, 5, 6]])
>>>

ところがdtypeの値を渡してstructured arrayにしようとするとタプルをリストでくくったものしかうまくいかない。(下の例では真ん中のコマンドだけうまくいっている。)

>>> # However when making a structured array, only tuple bracketed by list (middle) is correctly worked.
...
>>> np.array([[2,3,4],[2,5,6]], dtype=[('a','i4'),('b','i4'),('c','i4')])
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: expected a readable buffer object
>>>
>>> np.array([(2,3,4),(2,5,6)], dtype=[('a','i4'),('b','i4'),('c','i4')])
array([(2, 3, 4), (2, 5, 6)],
   dtype=[('a', '<i4'), ('b', '<i4'), ('c', '<i4')])
>>>
>>> np.array(((2,3,4),(2,5,6)), dtype=[('a','i4'),('b','i4'),('c','i4')])
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
ValueError: size of tuple must match number of fields.
>>>
>>> # Well, a structured array consists of tuples.

structured arrayというのはタプルを配列にしたものであるようだ。
で、次のようにした。

>>> # Then, the answer is here.
...
>>> y2 = np.array(list(tuple(z) for z in x), dtype=[('name1','u1'), ('name2', 'i4'), ('name3', 'S20')])
>>> y2
array([(1, 2, 'a'), (3, 4, 'b')],
   dtype=[('name1', '|u1'), ('name2', '<i4'), ('name3', '|S20')])

7.1.13

ターミナルでファイルから指定した行だけ表示する

head, tail が便利。
$ head -n 3 sample.txt
とすると、sample.txtの始めから3行表示される。

$ tail -n 3 sample.txt
とすると、sample.txtの後ろから3行表示される。

$ tail -n +3 sample.txt
とすると、sample.txtの始めから3行以降すべての行が表示される。

これらを組み合わせて、3行目から 5行目まで表示するには、
$ tail -n +3 sample.txt | head -n 3
とすればよい。tailで3行目以降を表示させ、その結果の始めから3行を表示するというコマンドだ。

さらにcat -nも使えば行番号を表示され、より見やすくなる。
$ cat -n sample.txt | tail -n +3 | head -n 3
logを見るときなどに便利。