Remrinのpython攻略日記

python3に入門しました。python3についてあれこれとサンプルコードとか。

NumPyの使い方(7) 統計関数、最大・最小

NumPyの統計関数の使い方

 
ndarray配列全体、あるいは特定の軸についての統計処理をする。
sumやmeanなどの集計処理は次元削減になる。
axis=0 縦方向にreduce
axis=1 横方向にredece
  

sum 和。 長さ0の配列では0を返す。
mean 平均。長さ0の配列ではNaNを返す。
var 分散
std 標準偏差
min 最小値, aminも同じ
max 最大値, amaxも同じ
nanmin NaNを無視した最小値
nanmax NaNを無視した最大値
minimun 2つの配列を比較して小さい要素、NaNを優先
maximun 2つの配列を比較して大きい要素、NaNを優先
fmin 2つの配列を比較して小さい要素、NaNを無視
fmax 2つの配列を比較して小さい要素、NaNを無視
argmin 最小値のインデックス
argmax 最大値のインデックス
cumsum 累積和
cumprod 累積積

maximumやfmaxでは予めNaNを処理したほうがよさそう。
 

import numpy as np

a1 = np.array([[1, 2], [3, 4]])
a2 = np.array([[0, 5], [2, 6]])
a3 = np.array([[0, 5], [2, np.nan]])

print(a1.max(axis=0))     # [3 4]
print(a1.max(axis=1))     # [2 4]
print(a1.max())           # 4
print(a1.argmax())        # 3  : 1次元配列にし、3番要素が最大値
print(a3.max())           # nan
print(np.nanmax(a3))      # 5.0
     
print(np.maximum(a1, a2)) # [[1 5]
                          #  [3 6]]
print(np.maximum(a1, a3)) # [[1 5]
                          #  [3 nan]]  RuntimeWarning: invalid value encountered in maximum
print(np.fmax(a1, a3))    # [[ 1.  5.]
                          # [ 3.  4.]] RuntimeWarning: invalid value encountered in fmax     

 

mean(), sum()

a1 = np.arange(12).reshape(3, 4)
print(a1)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]

# mean
print(a1.mean())   # 4.0  メソッド
print(np.mean(a1)) # 4.0  関数

# axisを指定すると1次元低い配列を取得     
print(np.mean(a1, 0))      # [ 4.  5.  6.  7.]
print(np.mean(a1, axis=0)) # [ 4.  5.  6.  7.]
print(np.mean(a1, 1))      # [ 1.5  5.5  9.5]
print(np.mean(a1, axis=1)) # [ 1.5  5.5  9.5]
#print(np.mean(a1, 2))     IndexError: tuple index out of range

print(a1.sum())   # 66
print(np.sum(a1)) # 66
print(a1.sum(0))  # [12 15 18 21]
print(a1.sum(1))  # [ 6 22 38]

 

累積和cumsum(), 累積積cumprod()

a2 = np.ones((3, 4), dtype=int)
a2*= 2
print(a2)
# [[2 2 2 2]
#  [2 2 2 2]
#  [2 2 2 2]]

print(np.cumsum(a2, 0))
# [[2 2 2 2]
#  [4 4 4 4]
#  [6 6 6 6]]

print(np.cumsum(a2, 1))
# [[2 4 6 8]
#  [2 4 6 8]
#  [2 4 6 8]]

print(np.cumprod(a2, 0))
# [[2 2 2 2]
#  [4 4 4 4]
#  [8 8 8 8]]

print(np.cumprod(a2, 1))
# [[ 2  4  8 16]
#  [ 2  4  8 16]
#  [ 2  4  8 16]]

print(np.cumsum(a2))
# [ 2  4  6 ..., 20 22 24]

 

NumPyの使い方(6) 条件制御

NumPyの条件制御について。
 
if~elseで条件分岐をするとき

a = 5
if a >= 0:
    b = 1
else:
    b = -1

と書けますが、これを3項演算子を使い以下のようにも書けます。

b = 1 if a >= 0 else -1

 
似たような動作を組み込みのリスト型で行うとき、
例えば、Trueならlist1から、そうでなければlist2から要素を選ぶとき、

list1 = [1, 2, 3, 4, 5]
list2 = [11, 12, 13, 14, 15]
condi = [True, False, True, False, True]

list3 = [x if c else y for (c, x, y) in zip(condi, list1, list2)]
print(list3)   # [1, 12, 3, 14, 5]

 
NumPyではnp.where()を使って
np.where(条件, x, y)のように書きます。
x,yは配列または数値。数値ならブロードキャストされる。

a3 = np.where(condi, list1, list2)
print(a3)     # [ 1 12  3 14  5]

 
他の例も

a1 = np.arange(9).reshape(3, 3)
print(a1)
# [[0 1 2]
#  [3 4 5]
#  [6 7 8]]

# 3未満の要素を0で置き換える(1)
print(np.where(a1 < 3, 0, a1))
# [[0 0 0]
#  [3 4 5]
#  [6 7 8]]

# 3未満の要素を0で置き換える(2)
print(np.where(a1 >= 3, a1, 0))
# [[0 0 0]
#  [3 4 5]
#  [6 7 8]]

# 正なら1、正でないなら-1にする
print(np.where(a1 > 0, 1, -1))
# [[-1  1  1]
#  [ 1  1  1]
#  [ 1  1  1]]

 
np.where()の引数を条件の配列だけにすると、
Trueとなる要素のインデックスを取得。

a1 = np.arange(9).reshape(3, 3)
print(a1)
# [[0 1 2]
#  [3 4 5]
#  [6 7 8]]

# Trueとなる要素のインデックスを取得
print(np.where(a1 > 5))
# (array([2, 2, 2], dtype=int32), array([0, 1, 2], dtype=int32))

# そのインデックスを利用して、要素を取り出せる。
print(a1[np.where(a1 > 5)])
# [6 7 8]

# Trueとなる要素のインデックスを取得
print(np.where(a1 > 2))
# (array([1, 1, 1, 2, 2, 2], dtype=int32), array([0, 1, 2, 0, 1, 2], dtype=int32))

# そのインデックスを利用して、要素を取り出せる。
print(a1[np.where(a1 > 2)])
# [3 4 5 6 7 8]

# 値の検索
target = [3, 4, 7]
ix = np.in1d(a1.ravel(), target).reshape(a1.shape)
print(ix)
# [[False False False]
#  [ True  True False]
#  [False  True False]]

# そのインデックスを表示
print(np.where(ix))
# (array([1, 1, 2], dtype=int32), array([0, 1, 1], dtype=int32))

 

2つの条件を同時に判断

cond1がTrueでcond2もTrue 3
cond1がTrueでcond2はFalse 2
cond1がFalseでcond2はTrue 1
cond1がFalseでcond2もFalse 0

としたい場合は、python標準だとif, elifなどを組み合わせて書けるが、
np.whereを3回ネストしても書ける

cond1 = np.array([True, True, False, False])
cond2 = np.array([True, False, True, False])
result = np.where(cond1 & cond2, 3,
                  np.where(cond1, 2,
                           np.where(cond2, 1, 0)))
print(result)   # [3 2 1 0]

True=1, False=0であることを使い次のようにも書ける。

result = cond1 * 2 + cond2
print(result)   # [3 2 1 0]

NumPyの使い方(5) ベクトル演算とユニバーサル関数

ベクトル演算とユニバーサル関数について。

ベクトル演算

 ndarrayと数値(スカラー)の計算は全要素対象で、forループを使わない。
 ndarrayどうしの演算は対応する位置の要素どうしで計算。
 [注意]ndarray * ndarrayは内積外積にはならない。

import numpy as np

a1 = np.arange(6).reshape(2, 3)
print(a1)
# [[0 1 2]
#  [3 4 5]

print(a1 + 1)
# [[1 2 3]
#  [4 5 6]

print(a1 - 1)
# [[-1  0  1]
#  [ 2  3  4]

print(a1 * 2)
# [[ 0  2  4]
#  [ 6  8 10]

print(a1 / 10)
# [[ 0.   0.1  0.2]
#  [ 0.3  0.4  0.5]

print(a1 ** 2)
# [[ 0  1  4]
#  [ 9 16 25]

print(a1 +a1)
# [[ 0  2  4]
#  [ 6  8 10]]

print(a1 * a1)
# [[ 0  1  4]
#  [ 9 16 25]]

 

ユニバーサル関数(ufunc, universal function)

 ベクトル演算と同様に、要素ごとに計算される。
 引数となる配列が1つのとき「単項ufunc」、2つのとき「2項ufunc」

例:

a1 = np.arange(6)
a2 = np.arange(0, 60, 10)

# 単項ユニバーサル関数の例
print(np.square(a1))
# [ 0  1  4  9 16 25]

# 2項ユニバーサル関数の例
print(np.add(a1, a2))
# [ 0 11 22 33 44 55]

 
単項ufunc

abs 整数、小数、複素数の絶対値
fabs 整数、小数の絶対値。高速
sqrt 平方根。 array**0.5と同等
square 2乗。 array**2と同等
exp eを底としたべき乗
log 自然対数。底がe
log10 常用対数。底が10
log2 底が2の対数
log1p 1を加えてからの自然対数
sign 要素の符号を返す。正:+1, 負:-1, ゼロ:0
ceil 切り上げ
floor 切り捨て
rint dtypeそのままで、四捨五入
modf 整数部分と小数部分の2つの配列を返す
isnan NaNかどうかの真偽値
isfinite True:Nanでもinfでもない。False:NaNかinf
isinf infかどうか。
sin 三角関数
cos  
tan  
sinh 双曲線関数
cosh  
tanh  
arcsin 三角関数
arcsos  
arctan  
arcsinh 双曲線関数
arccosh  
arctanh  
logical_not 論理否定。-arrayと同等

 
2項unfnc

add
subtract
multiply
divide
floor_divide 商を左方向へ丸める。//
power 累乗
maximum 最大値。NaNがあるときはNaNを選ぶ
minimum 最小値。NaNがあるときはNaNを選ぶ
fmax 最大値。NaNがあるときはNaNではない方
fmin 最小値。NaNがあるときはNaNではない方
mod 剰余
copysign 1つめの配列の絶対値を2つめの配列の符号に。
greater >
greater_equal >=
less
less_equal <=
equal ==
not_equal !=
logical_and & 論理和
logical_or 論理積
logical_xor ^ 排他

 
・np.vectorize()を使って自作の関数をufuncにできる。

def myfunc(x, y):
    return x + y
vfunc = np.vectorize(myfunc)

print(vfunc(np.arange(5), 10))
# [10 11 12 13 14]

 

Project Euler

Project Euler problem #001 Multiples of 3 and 5

 
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
 
問題1:1000未満の3または5の倍数の和を求めよ。
 
forループを使っていくのが自然かな。

# forループとif
limit = 1000
result = 0
for i in range(limit):
    if i%3 == 0 or i%5 ==0:
        result += i
print(result)

 
ifの部分は3項演算子でも。

# forループと3項演算子
limit = 1000
result = 0
for i in range(limit):
    result += i if i%5 == 0 or i%3 ==0 else 0
print(result)

 
リスト内包表記を使うとシンプルに。

# リスト内包表記
limit = 1000
result = sum([x for x in range(limit) if x%3 == 0 or x%5 ==0 ])
print(result)

 
3つの等差数列に分けても。

# 等差数列のsum()
limit = 1000
result = sum(range(0, limit, 3)) + sum(range(0, limit, 5)) - sum(range(0, limit, 15))
print(result)

 
等差数列の和の公式を使うと、コードは複雑になるけど処理時間は大幅短縮。

# 等差数列の和の公式
limit = 1000
def sum_multi(x):
    first = x
    last = (limit - 1) - (limit - 1) % x 
    return int((first + last) * (last / x) / 2)
result = sum_multi(3) + sum_multi(5) - sum_multi(15)
print(result)

 

Project Euler problem #002 Even Fibonacci numbers

 
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
 
問題2:フィボナッチ数列で400万以下の偶数の項の和を求めよ。
 

def fib4():
    a, b = 0, 1
    result = 0
    while b < 4*10**6:
        result += b if b % 2 ==0 else 0
        a, b = b, a + b
    return result

print(fib4())
# 4613732

 
フィボナッチ数列の偶数項は3項ごとに登場。
それと、フィボナッチ数列の生成をlambda式で1行にまとめてみると、

f = lambda x:int(((1 + 5**0.5) / 2)**i / 5**0.5 + 0.5)
i, result = 3, 0
while f(i) < 4*10**6:
    result += f(i)
    i += 3
print(result)

 

Project Euler problem #003 Largest prime factor

The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
 
問題3:600851475143の素因数のうち最大のものを求めよ。
 

# 素数のジェネレータ
def gen2(start=2, stop=1000000):
    pr = max(1, start - 1)
    while True:
        while pr < stop:
            pr += 1
            if all(pr%x != 0 for x in range(2, int(pr**0.5) + 1)):
                break
        yield pr

# 素因数分解
def factorial(n):
    if n in [0, 1]:
        return [n]
    result = []
    stop = int(n**0.5) + 1
    g = gen2()
    pr = next(g)
    while pr < stop:
        if n % pr == 0:
            result.append(pr)
            n //= pr
            continue
        pr = next(g)
    if n > 1:
        result.append(n)
    return result

print(max(factorial(600851475143)))
# 6857

 

Project Euler problem #004 Largest palindrome product

 
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers.
 
問題:3桁の2つの数の積で作った回文のうち最大のものを求めよ。
 
forループを2重にして回文判定するとよさそう。

result = 0
for i in range(100, 1000):
    for j in range(i, 1000):
        if str(i * j) == str(i * j)[::-1]:
            result = max(result, i * j)
print(result)
# 906609

 
端が9と仮定すると、奇数×奇数なので、forループは奇数で。 

result = 0
for i in range(901, 1000, 2):
    for j in range(i, 1000, 2):
        if str(i * j) == str(i * j)[::-1]:
            result = max(result, i * j)
print(result)

 
積の1の位が9になるのは1×9、3×3、7×7、9×1なので、さらにループを減らせそう。

result = 0
pair9 = {1:8, 3:0, 7:0, 9:2}
for i in range(901, 1000, 2):
    if i%10 in pair9:                  # 1の位が1,3, 7, 9なら
        incre = pair9[i%10]            # 相手の1の位が決まる
    else:
        continue
    for j in range(i+incre, 1000, 10): # 1の位は固定なのでstep=10
        if str(i * j) == str(i * j)[::-1]:
            result = max(result, i * j)
print(result)

Archived Problems - Project Euler

テストデータ(6) メフィスト賞

メフィスト賞
 

import pandas as pd

url = 'http://python-remrin.hatenadiary.jp/entry/2017/05/10/222443'
## DataFrameのリストを得る。header=0のオプション指定で、最初の行をheader扱い。
fetched = pd.io.html.read_html(url)
print(len(fetched))  # listの要素であるDataFrameの個数
df = fetched[0]

# 2次元リスト化
data = []
for i in range(len(df)):
    x = []
    for j in range(len(df.iloc[0])):
        x.append(df.iloc[i, j])
    data.append(x)
print(data)

# hatena表組み化
for i in range(len(df)):
    s = "|"
    for j in range(len(df.iloc[0])):
        s += str(df.iloc[i, j]) + "|"
    print(s)

 

回数 作品名 著者名
1 すべてがFになる 森博嗣
2 コズミック 清涼院流水
3 六枚のとんかつ 蘇部健一
4 Jの神話 乾くるみ
5 記憶の果て 浦賀和宏
6 歪んだ創世記 積木鏡介
7 血塗られた神話 新堂冬樹
8 ダブ(エ)ストン街道 浅暮三文
9 QED 百人一首の呪 高田崇史
10 Kの流儀 中島望
11 銀の檻を溶かして 高里椎奈
12 ドッペルゲンガー 霧舎巧
13 ハサミ男 殊能将之
14 UNKNOWN 古処誠二
15 真っ暗な夜明け 氷川透
16 ウェディング・ドレス 黒田研二
17 火蛾 古泉迦十
18 日曜日の沈黙 石崎幸二
19 煙か土か食い物 舞城王太郎
20 月長石の魔犬 秋月涼介
21 フリッカー式 鏡公彦にうってつけの殺人 佐藤友哉
22 DOOMSDAY 審判の夜 津村巧
23 クビキリサイクル 青色サヴァンと戯れ言遣い 西尾維新
24 『クロック』城殺人事件 北山猛邦
25 それでも警官は微笑う 日明恩
26 死都日本 石黒耀
27 フレームアウト 生垣真太郎
28 蜜の森の凍える女神 関田涙
29 空を見上げる古い歌を口ずさむ 小路幸也
30 極限推理コロシアム 矢野龍王
31 冷たい校舎の時は止まる 辻村深月
32 孤虫症 真梨幸子
33 黙過の代償 森山赳志
34 少女は踊る暗い腹の中踊る 岡崎隼人
35 天帝のはしたなき果実 古野まほろ
36 ウルチモ・トルッコ 犯人はあなただ! 深水黎一郎
37 パラダイス・クローズド THANATO 汀こるもの
38 掘割で笑う女 浪人左門あやかし指南 輪渡颯介
39 マネーロード 二郎遊真
40 無貌伝 双児の子ら 望月守宮
41 虫とりのうた 赤星香一郎
42 プールの底に眠る 白河三兎
43 キョウカンカク 天祢涼
44 琅邪の鬼 丸山天寿
45 図書館の魔女 高田大介
46 恋都の狐さん 北夏輝
47 眼球堂の殺人 The Book 周木律
48 愛の徴 天国の方角 近本洋一
49 渦巻く回廊の鎮魂曲 冷媒探偵アーネスト 風森章羽
50 ○○○○○○○○殺人事件 早坂吝
51 恋と禁忌の述語論理 井上真偽
52 誰かが見ている 宮西真冬

テストデータ(5) 直木賞

直木賞

import pandas as pd
url = 'http://python-remrin.hatenadiary.jp/entry/2017/05/10/215715'
## DataFrameのリストを得る。header=0のオプション指定で、最初の行をheader扱い
fetched = pd.io.html.read_html(url)
print(len(fetched))  # 1   listの要素であるDataFrameの個数
df = fetched[0]

# 2次元リスト化
data = []
for i in range(len(df)):
    x = []
    for j in range(len(df.iloc[0])):
        x.append(df.iloc[i, j])
    data.append(x)
print(data)

# hatena表組み化
for i in range(len(df)):
    s = "|"
    for j in range(len(df.iloc[0])):
        s += str(df.iloc[i, j]) + "|"
    print(s)

 
直木賞

作者 作品
156回(2016年下半期) 恩田陸 蜂蜜と遠雷
155回(2016年上半期) 荻原浩 海の見える理髪店
154回(2015年下半期) 青山文平 つまをめとらば
153回(2015年上半期) 東山彰良
152回(2014年下半期) 西加奈子 サラバ!
151回(2014年上半期) 黒川博行 破門
150回(2013年下半期) 朝井まかて 恋歌
150回(2013年下半期) 姫野カオルコ 昭和の犬
149回(2013年上半期) 桜木紫乃 ホテルローヤル
148回(2012年下半期) 安部龍太郎 等伯
148回(2012年下半期) 朝井リョウ 何者
147回(2012年上半期) 辻村深月 鍵のない夢を見る
146回(2011年下半期) 葉室麟 蜩ノ記
145回(2011年上半期) 池井戸潤 下町ロケット
144回(2010年下半期) 木内 昇 漂砂のうたう
144回(2010年下半期) 道尾秀介 月と蟹
143回(2010年上半期) 中島京子 小さいおうち
142回(2009年下半期) 白石一文 ほかならぬ人へ
142回(2009年下半期) 佐々木譲 廃墟に乞う
141回(2009年上半期) 北村薫 鷺と雪
140回(2008年下半期) 天童荒太 悼む人
140回(2008年下半期) 山本兼一 利休にたずねよ
139回(2008年上半期) 井上荒野 切羽へ
138回(2007年下半期) 桜庭一樹 私の男
137回(2007年上半期) 松井今朝子 吉原手引草
136回(2006年下半期) - -
135回(2006年上半期) 三浦しをん まほろ駅前多田便利軒
135回(2006年上半期) 森絵都 風に舞いあがるビニールシート
134回(2005年下半期) 東野圭吾 容疑者Xの献身
133回(2005年上半期) 朱川湊人 花まんま
132回(2004年下半期) 角田光代 対岸の彼女
131回(2004年上半期) 奥田英朗 空中ブランコ
131回(2004年上半期) 熊谷達也 邂逅の森
130回(2003年下半期) 江國香織 号泣する準備はできていた
130回(2003年下半期) 京極夏彦 後巷説百物語
129回(2003年上半期) 石田衣良 4TEEN
129回(2003年上半期) 村山由佳 星々の舟
128回(2002年下半期) - -
127回(2002年上半期) 乙川優三郎 生きる
126回(2001年下半期) 山本一力 あかね空
126回(2001年下半期) 唯川恵 肩ごしの恋人
125回(2001年上半期) 藤田宜永 愛の領分
124回(2000年下半期) 重松清 ビタミンF
124回(2000年下半期) 山本文緒 プラナリア
123回(2000年上半期) 金城一紀 GO
123回(2000年上半期) 船戸与一 虹の谷の五月
122回(1999年下半期) なかにし礼 長崎ぶらぶら節
121回(1999年上半期) 佐藤賢一 王妃の離婚
121回(1999年上半期) 桐野夏生 柔らかな頬
120回(1998年下半期) 宮部みゆき 理由
119回(1998年上半期) 車谷長吉 赤目四十八瀧心中未遂
118回(1997年下半期) - -
117回(1997年上半期) 篠田節子 女たちのジハード
117回(1997年上半期) 浅田次郎 鉄道員(ぽっぽや)
116回(1996年下半期) 坂東眞砂子 山妣
115回(1996年上半期) 乃南アサ 凍える牙
114回(1995年下半期) 小池真理子
114回(1995年下半期) 藤原伊織 テロリストのパラソル
113回(1995年上半期) 赤瀬川隼 白球残映
112回(1994年下半期) - -
111回(1994年上半期) 海老沢泰久 帰郷
111回(1994年上半期) 中村彰彦 二つの山河
110回(1993年下半期) 大沢在昌 新宿鮫 無間人形
110回(1993年下半期) 佐藤雅美 恵比寿屋喜兵衛手控え
109回(1993年上半期) 高村薫 マークスの山
109回(1993年上半期) 北原亞以子 恋忘れ草
108回(1992年下半期) 出久根達郎 佃島ふたり書房
107回(1992年上半期) 伊集院静 受け月
106回(1991年下半期) 高橋克彦 緋い記憶
106回(1991年下半期) 高橋義夫 狼奉行
105回(1991年上半期) 芦原すなお 青春デンデケデケデケ
105回(1991年上半期) 宮城谷昌光 夏姫春秋
104回(1990年下半期) 古川薫 漂泊者のアリア
103回(1990年上半期) 泡坂妻夫 蔭桔梗
102回(1989年下半期) 原【りょう】 私が殺した少女
102回(1989年下半期) 星川清司 小伝抄
101回(1989年上半期) 笹倉明 遠い国からの殺人者
101回(1989年上半期) ねじめ正一 高円寺純情商店街
100回(1988年下半期) 杉本章子 東京新大橋雨中図
100回(1988年下半期) 藤堂志津子 熟れてゆく夏
99回(1988年上半期) 景山民夫 遠い海から来たCOO
99回(1988年上半期) 西木正明 凍れる瞳・端島の女
98回(1987年下半期) 阿部牧郎 それぞれの終楽章
97回(1987年上半期) 山田詠美 ソウル・ミュージック ラバーズ・オンリー
97回(1987年上半期) 白石一郎 海狼伝
96回(1986年下半期) 逢坂剛 カディスの赤い星
96回(1986年下半期) 常盤新平 遠いアメリカ
95回(1986年上半期) 皆川博子 恋紅
94回(1985年下半期) 林真理子 最終便に間に合えば・京都まで
94回(1985年下半期) 森田誠吾 魚河岸ものがたり
93回(1985年上半期) 山口洋子 演歌の虫・老梅
92回(1984年下半期) - -
91回(1984年上半期) 連城三紀彦 恋文
91回(1984年上半期) 難波利三 てんのじ村
90回(1983年下半期) 高橋治 秘伝
90回(1983年下半期) 神吉拓郎 私生活
89回(1983年上半期) 胡桃沢耕史 黒パン俘虜記
88回(1982年下半期) - -
87回(1982年上半期) 村松友視 時代屋の女房
87回(1982年上半期) 深田祐介 炎熱商人
86回(1981年下半期) つかこうへい 蒲田行進曲
86回(1981年下半期) 光岡明 機雷
85回(1981年上半期) 青島幸男 人間万事塞翁が丙午
84回(1980年下半期) 中村正軌 元首の謀叛
83回(1980年上半期) 志茂田景樹 黄色い牙
83回(1980年上半期) 向田邦子 花の名前・かわうそ・犬小屋
82回(1979年下半期) - -
81回(1979年上半期) 阿刀田高 ナポレオン狂
81回(1979年上半期) 田中小実昌 浪曲師朝日丸の話・ミミのこと
80回(1978年下半期) 有明夏夫 大浪花諸人往来
80回(1978年下半期) 宮尾登美子 一絃の琴
79回(1978年上半期) 色川武大 離婚
79回(1978年上半期) 津本陽 深重の海
78回(1977年下半期) - -
77回(1977年上半期) - -
76回(1976年下半期) 三好京三 子育てごっこ
75回(1976年上半期) - -
74回(1975年下半期) 佐木隆三 復讐するは我にあり
73回(1975年上半期) - -
72回(1974年下半期) 半村良 雨やどり
72回(1974年下半期) 井出孫六 アトラス伝説
71回(1974年上半期) 藤本義一 鬼の詩
70回(1973年下半期) - -
69回(1973年上半期) 長部日出雄 津軽世去れ節・津軽じょんから節
69回(1973年上半期) 藤沢周平 暗殺の年輪
68回(1972年下半期) - -
67回(1972年上半期) 井上ひさし 手鎖心中
67回(1972年上半期) 綱淵謙錠
66回(1971年下半期) - -
65回(1971年上半期) - -
64回(1970年下半期) 豊田穣 長良川
63回(1970年上半期) 渡辺淳一 光と影
63回(1970年上半期) 結城昌治 軍旗はためく下に
62回(1969年下半期) - -
61回(1969年上半期) 佐藤愛子 戦いすんで日が暮れて
60回(1968年下半期) 早乙女貢 僑人の檻
60回(1968年下半期) 陳舜臣 青玉獅子香炉
59回(1968年上半期) - -
58回(1967年下半期) 三好徹 聖少女
58回(1967年下半期) 野坂昭如 アメリカひじき・火垂るの墓
57回(1967年上半期) 生島治郎 追いつめる
56回(1966年下半期) 五木寛之 蒼ざめた馬を見よ
55回(1966年上半期) 立原正秋 白い罌粟
54回(1965年下半期) 新橋遊吉 八百長
54回(1965年下半期) 千葉治平 虜愁記
53回(1965年上半期) 藤井重夫
52回(1964年下半期) 安西篤子 張少子(チャンシャオツ)の話
52回(1964年下半期) 永井路子 炎環
51回(1964年上半期) - -
50回(1963年下半期) 安藤鶴夫 巷談本牧亭
50回(1963年下半期) 和田芳恵 塵の中
49回(1963年上半期) 佐藤得二 女のいくさ
48回(1962年下半期) 山口瞳 江分利満氏の優雅な生活
48回(1962年下半期) 杉本苑子 孤愁の岸
47回(1962年上半期) 杉森久英 天才と狂人の間
46回(1961年下半期) 伊藤桂一 螢の河
45回(1961年上半期) 水上勉 雁の寺
44回(1960年下半期) 黒岩重吾 背徳のメス
44回(1960年下半期) 寺内大吉 はぐれ念仏
43回(1960年上半期) 池波正太郎 錯乱
42回(1959年下半期) 司馬遼太郎 梟の城
42回(1959年下半期) 戸板康二 團十郎切腹事件
41回(1959年上半期) 平岩弓枝 鏨師
41回(1959年上半期) 渡邊喜恵子 馬淵川
40回(1958年下半期) 城山三郎 総会屋錦城
40回(1958年下半期) 多岐川恭 落ちる
39回(1958年上半期) 山崎豊子 花のれん
39回(1958年上半期) 榛葉英治 赤い雪
38回(1957年下半期) - -
37回(1957年上半期) 江崎誠致 ルソンの谷間
36回(1956年下半期) 穂積驚 勝烏
36回(1956年下半期) 今東光 お吟さま
35回(1956年上半期) 今官一 壁の花
35回(1956年上半期) 南條範夫 燈台鬼
34回(1955年下半期) 邱永漢 香港
34回(1955年下半期) 新田次郎 強力伝
33回(1955年上半期) - -
32回(1954年下半期) 梅崎春生 ボロ家の春秋
32回(1954年下半期) 戸川幸夫 高安犬物語
31回(1954年上半期) 有馬頼義 終身未決囚
30回(1953年下半期) - -
29回(1953年上半期) - -
28回(1952年下半期) 立野信之 叛乱
27回(1952年上半期) 藤原審爾 罪な女・その他
26回(1951年下半期) 柴田錬三郎 エスの裔
26回(1951年下半期) 久生十蘭 鈴木主水
25回(1951年上半期) 源氏鶏太 英語屋さん・その他
24回(1950年下半期) 檀一雄 真説石川五右衛門長恨歌
23回(1950年上半期) 今日出海 天皇の帽子
23回(1950年上半期) 小山いと子 執行猶予
22回(1949年下半期) 山田克郎 海の廃園
21回(1949年上半期) 富田常雄 面・刺青
20回(1944年下半期) - -
19回(1944年上半期) 岡田誠三 ニューギニヤ山岳戦
18回(1943年下半期) 森荘已池 山畠・蛾と笹舟
17回(1943年上半期) - -
16回(1942年下半期) 田岡典夫 強情いちご・その他
16回(1942年下半期) 神崎武雄 寛容・その他
15回(1942年上半期) - -
14回(1941年下半期) - -
13回(1941年上半期) 木村荘十 雲南守備兵
12回(1940年下半期) 村上元三 上総風土記・その他
11回(1940年上半期) 堤千代 小指・その他
11回(1940年上半期) 河内仙介 軍事郵便
10回(1939年下半期) - -
9回(1939年上半期) - -
8回(1938年下半期) 大池唯雄 兜首・秋田口の兄弟
7回(1938年上半期) 橘外男 ナリン殿下への回想
6回(1937年下半期) 井伏鱒二 ジョン萬次郎漂流記・その他
5回(1937年上半期) - -
4回(1936年下半期) 木々高太郎 人生の阿呆
3回(1936年上半期) 海音寺潮五郎 天正女合戦・武道傳來記
2回(1935年下半期) 鷲尾雨工 吉野朝太平記
1回(1935年上半期) 川口松太郎 鶴八鶴次郎・風流深川唄

NumPyの使い方(4) 形状変換と転置

NumPyの形状変換と転置について。
 

reshape()、resize()

 タプルでshapeを指定して形状を変換する。
 変換前後で全要素数が一致しないときはValueError
 -1を指定した軸はNumPyが自動で判断。
 もとの配列を参照を得るので、値変更は元の配列に及ぶ。 
 np.resize()だと、コピーを取得するので、値変更をしても元の配列は保存される。
  np.resize()は総要素数が増えた場合は値を繰り返して埋める。
  ndarray.resize()は総要素数が増えたときはゼロで埋める。

import numpy as np

a1 = np.array(range(12))
print(a1)  # [0  1  2  3  4  5  6  7  8  9 10 11 12]

print(a1.reshape(4, 3))
# [[ 0  1  2]
#  [ 3  4  5]
#  [ 6  7  8]
#  [ 9 10 11]]

print(a1.reshape(4, 3).reshape(2, 6))
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]]

print(a1.reshape(6, -1))
# -1を指定した軸は、NumPyが自動で判断
#[[ 0  1]
# [ 2  3]
# [ 4  5]
# [ 6  7]
# [ 8  9]
# [10 11]]

# print(a1.reshape(6, 3))
# ValueError: total size of new array must be unchanged

 

flatten(), ravel()

 1次元の配列へ変換する。
 flatten() 必ずコピーを返す。
 raval()  必要がなければコピーは作らない。
 デフォルトでは行優先だが、列優先にする場合は"F"を引数にする。

a2 = np.arange(9).reshape(3, 3)
print(a2.flatten())
# [0 1 2 3 4 5 6 7 8]

print(a2.flatten("F"))
# [0 3 6 1 4 7 2 5 8]

 

転置.Tとtranspose()

・2次元配列の行列変換は.T
・transpose()は軸の順序を指定できる。
 
2次元配列のでの例

a1 = np.array(range(8)).reshape(4, 2)
print(a1)
# [[0 1]
#  [2 3]
#  [4 5]
#  [6 7]]

print(a1.T)
# [[0 2 4 6]
#  [1 3 5 7]]

# a1.T と a1 の内積
print(np.dot(a1.T, a1))
# [[56 68]
#  [68 84]]

print(a1.transpose(0, 1))
# 元の配列を同じ形
# [[0 1]
#  [2 3]
#  [4 5]
#  [6 7]]

print(a1.transpose(1, 0))
# 元の配列の0番の軸(行)を1番の軸(縦)に、1番軸を0番に
# [[0 2 4 6]
#  [1 3 5 7]]

 

・transpose(2, 0, 1)とは
 3次元配列で、shapeが(元の2番軸, 元の0番軸, 元の1番軸)にすることを表す。
 
3次元配列での例

a1 = np.array(range(24)).reshape(2, 3, 4)
print(a1)
# [[[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]
#
#  [[12 13 14 15]
#   [16 17 18 19]
#   [20 21 22 23]]]

print(a1.transpose(0, 1, 2))
# 元の配列と同じ
# [[[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]
#
#  [[12 13 14 15]
#   [16 17 18 19]
#   [20 21 22 23]]]

print(a1.transpose(0, 2, 1))
# 最も外側の次元は変えずに内側の行と列を入れ替える
# shapeは(2, 4, 3)となる。
# [[[ 0  4  8]
#   [ 1  5  9]
#   [ 2  6 10]
#   [ 3  7 11]]
#
#  [[12 16 20]
#   [13 17 21]
#   [14 18 22]
#   [15 19 23]]]

print(a1.transpose(1, 0, 2))
# transpose(1, 0, 2)とは、shapeが(元の1番軸、元の0番軸、元の2番軸)
# 列は変えずに、行と外側を入れ替えて、shapeは(3, 2, 4)となる。
# [[[ 0  1  2  3]
#   [12 13 14 15]]
#
#  [[ 4  5  6  7]
#   [16 17 18 19]]
#
#  [[ 8  9 10 11]
#   [20 21 22 23]]]

 
・3次元配列の軸の方向に注意
f:id:rare_Remrin:20170513132338p:plain
 

swapaxes()

・swapaxes()で特定の2つの軸を入れかれられる。
 「axes」は「axis」の複数形。
 3次元配列でswapaxes(0, 2)だと、0番軸と2番軸を交換する。
 つまり、transpose(2, 1, 0)と同義

 2次元配列での転置.Tは、swapaxes(1, 0)と同義。

print(a1.swapaxes(0, 1))  # transpose(1, 0, 2)と同義
# [[[ 0  1  2  3]
#   [12 13 14 15]]
#
#  [[ 4  5  6  7]
#   [16 17 18 19]]
#
#  [[ 8  9 10 11]
#   [20 21 22 23]]]