このコードをPythonicとして記述したいと思います。私の実際の配列はこの例よりもはるかに大きいです。
(5 + 10 + 20 + 3 + 2)/ 5
print(np.mean(array、key = lambda x:x [1]))TypeError:mean()が予期しないキーワード引数 'key'を取得しました
array = [('a', 5) , ('b', 10), ('c', 20), ('d', 3), ('e', 2)]
sum = 0
for i in range(len(array)):
sum = sum + array[i][1]
average = sum / len(array)
print(average)
import numpy as np
print(np.mean(array,key=lambda x:x[1]))
どうすればこれを回避できますか? 2番目の例を使用します。
私はPython 3.7を使用しています
Python 3.4以降)を使用している場合は、 statistics
モジュールを使用できます。
from statistics import mean
average = mean(value[1] for value in array)
または、Python 3.4より古いバージョン)を使用している場合:
average = sum(value[1] for value in array) / len(array)
これらのソリューションは両方ともPythonジェネレータ式と呼ばれる)のナイス機能を使用しています。ループ
value[1] for value in array
タイムリーでメモリ効率の良い方法で新しいシーケンスを作成します。 PEP 289-Generator Expressions を参照してください。
Python 2を使用していて、整数を合計している場合、整数除算が行われ、結果が切り捨てられます。例:
>>> 25 / 4
6
>>> 25 / float(4)
6.25
整数除算がないことを確認するために、sum
の開始値をfloat
値0.0
に設定できます。ただし、これは、括弧でジェネレータ式を明示的にする必要があることも意味します。そうでない場合は、構文エラーであり、コメントに記載されているように、あまりきれいではありません。
average = sum((value[1] for value in array), 0.0) / len(array)
fsum
from math
を使用するのがおそらく最善ですfloat
を返すモジュール:
from math import fsum
average = fsum(value[1] for value in array) / len(array)
numpy
を使用する場合は、numpy.array
にキャストし、numpy
インデックスを使用して目的の軸を選択します。
import numpy as np
array = np.array([('a', 5) , ('b', 10), ('c', 20), ('d', 3), ('e', 2)])
print(array[:,1].astype(float).mean())
# 8.0
元の配列は文字列と数値の両方を含み、したがってobject
型であるため、数値型へのキャストが必要です。この場合、float
またはint
を使用できますが、違いはありません。
よりゴルフに似たソリューションを利用できる場合は、配列をバニラパイソンで転置し、数値のみのリストを取得して、平均を計算できます。
sum(Zip(*array)[1])/len(array)
リスト内包表記の代わりにmap
を使用できます
sum(map(lambda x:int(x[1]), array)) / len(array)
またはfunctools.reduce
(Python2.Xを使用している場合はreduce
ではなくfunctools.reduce
)
import functools
functools.reduce(lambda acc, y: acc + y[1], array, 0) / len(array)
あなたは単に使うことができます:
print(sum(tup[1] for tup in array) / len(array))
またはPython 2:
print(sum(tup[1] for tup in array) / float(len(array)))
またはPython 2:
from math import fsum
print(fsum(tup[1] for tup in array) / len(array))
純粋なPythonの場合:
from operator import itemgetter
acc = 0
count = 0
for value in map(itemgetter(1), array):
acc += value
count += 1
mean = acc / count
データがlist
としてメモリに収まらない場合は、反復的なアプローチが望ましい場合があります(これは大きいと言ったためです)。可能であれば、宣言的なアプローチを優先します。
data = [sub[1] for sub in array]
mean = sum(data) / len(data)
numpy
を使用することに心を開いているなら、私はこのクリーナーを見つけます:
a = np.array(array)
mean = a[:, 1].astype(int).mean()
map
を使用できます:
np.mean(list(map(lambda x: x[1], array)))
ここでの問題は、すべての値がndarray
にキャストされるため、タプルのリストの平均をstr
として直接計算できないことです。
ただし、これを回避するには、タプルのリストから 構造化配列 を定義して、タプルの各要素に異なるデータ型を関連付けることができます。
したがって、次のようにタプルのリストから構造化配列を定義できます。
l = [('a', 5) , ('b', 10), ('c', 20), ('d', 3), ('e', 2)]
a = np.array(l, dtype=([('str', '<U1'), ('num', '<i4')]))
そして、単純に np.mean
数値フィールド、つまりタプルの2番目の要素:
np.mean(a['num'])
# 8.0
リストの要素の合計と数を使用して平均を見つけるだけです。
array = [('a', 5) , ('b', 10), ('c', 20), ('d', 3), ('e', 2)]
avg = float(sum(value[1] for value in array)) / float(len(array))
print(avg)
#8.0