2017-04-17 5 views
0

私のタイトルがまさに私がやろうとしているものなのかどうかわかりませんが、本質的にリストのリストの平均を得ています。リストの中ではなくリストの中に追加したいと思っています:pythonでループを反転しますか?

listoflists = [[1,2,3], [1,0,4], [0,5,1]] 
#want [1, 3.5, 2.67] 
final = [] 
for i in range(len(listoflists)): 
    count = 0 
    val = 0 
    for j in range(len(listoflists[i])): 
     if listoflists[i][j] != 0: 
      count += 1 
      val += listoflists[i][j] 
    final.append(float(val)/count) 
print final #currently returns [2.0, 2.5, 3.0] 

平均6/3 = 2を追加する代わりに、1,1,0(各リストの最初の値)を追加し、2/2 = 1を得る(0 、それを数えないでください) 代わりにそれを行うためにループを取得するにはどうすればよいですか?

+2

[zip()](https://docs.python.org/3/library/functions.html#zip)を使用してリストのリストを転記し、[sum()](https:// docs。 python.org/3/library/functions.html#sum)を使用して、転置リストの合計を取得します。 – wwii

答えて

0

あなたはジップ

zip(*listoflists) 
>>> [(1, 1, 0), (2, 0, 5), (3, 4, 1)] 

を使用して、最初のリストに変換することができますがここでそれを行うための一つの方法です:

final = [] 
for l in zip(*listoflists): 
    final.append(float(sum(l))/len([x for x in l if x != 0])) 
print final 
0

あなたがnumpyのを使用することができます。

arr = np.array(listoflists) 
sums = arr.sum(axis=0) 
final = []  
for i in range(arr.shape[1]): 
    final.append(sums[i]/np.count_nonzero(arr[:,i]) 

また、ループ全体を避ける方が良い。

arr = np.array(listoflists) 
sums = arr.sum(0) 
non_zeros = (arr != 0).sum(0) 
final = sums/zon_zeros 
0

これはあなたのために動作します:

listoflists = [[1,2,3], [1,0,4], [0,5,1]] 
second_list = zip(*listoflists) 
new_list = map(list, second_list) 

final_list = [] 
without_zero = [] 
for i in new_list: 
    for b in i: 
     if b != 0: 
      without_zero.append(b) 
    final_list.append(without_zero) 
    without_zero = [] 

average = [sum(i)/float(len(i)) for i in final_list] 

print average 

編集:ちょうどリスト内包とzipファイルを使用して 別の方法:

listoflists = [[1,2,3], [1,0,4], [0,5,1]] 
new_list = zip(*listoflists) 
result = [sum([i for i in b if i != 0])/float(len([i for i in b if i != 0])) for b in new_list] 
print result 
0
from __future__ import division 
map(lambda *column: sum(column)/sum(x>0 for x in column), *listoflists) 

別の可能性(のみPythonの3):

from statistics import mean 
[mean(filter(None, column)) for column in zip(*listoflists)] 

代替numpyの実装は、(同様のPython 2の作品):

import numpy as np 
a = np.array(listoflists) 
np.average(a, axis=0, weights=a>0) 
0

のようなもう少しPythonのようにあなたのコードを改革することができます。 Pythonでは、(リストを参照して)反復処理を行い、オブジェクトを直接取得することができます。実際にインデックスを使用する必要はありません。

final = [] 
for i in listoflists: 
    count = 0 
    val = 0 

    for j in i: 
     if j != 0: 
      count += 1 
      val += j 
    final.append(float(val)/count) 

print final 

このコードでは、インデックス化することなく、あなたとまったく同じであるjは、私たちが得ている実際のサブ項目(番号)です。


あなたがやりたい、Pythonはサブリストを転置便利zip()機能を持っています。私たちはこれらのリストをzip([1,2],[3,4])ときに我々は、以下のリスト[1,2] , [3,4]を持っている場合たとえば、我々はリストのリストの前に*記号を使用してリストをアンパックすることにより、あなたがやりたいためにこれを使用することができます[(1, 3), (2, 4)]

を取得し、zip()はこれをサポートしています。前の例に戻って、リストx = [[1,2],[3,4]]のリストを作成し、*でxをzipに渡して、われわれが望むものを得ることができます。 zip(*x)[(1, 3), (2, 4)]となります。あなたが持っているものと一緒にこれらを組み合わせることで、あなたの望む結果が得られます。

final = [] 
for i in zip(*listoflists): 
    count = 0 
    val = 0 

    for j in i: 
     if j != 0: 
      count += 1 
      val += j 
    final.append(float(val)/count) 

私たちは、可能な場合は、リスト内のすべての項目を合計し、すでにfilter()で使用することができますlen()を知っているにもよりsum()として複数のそのようなから構築されたいくつかを使用することによって、これを向上させることができます0を除外します。ドキュメントから:

(アイテムの場合、繰り返し可能なアイテムのアイテム)機能がない場合

だから我々がチェックされているリストは、価値のあるアイテムのが含まれており、0がある場合ときif 0:

final = [] 
for i in zip(*listoflists): 
    if i: 
     final.append(float(sum(i))/len(filter(None, i))) 
print final 

失敗した私たちは、いずれかを使用して、さらに一歩進み、機能を圧縮することができます

print [float(sum(i))/len(filter(None,i)) for i in zip(*listoflists)] 

注一部:Pythonは、list comprehensionsを提供しているneatestもののこれらの回答のうち、他のものほど最適ではないかもしれませんが、私の答えは組み込み機能だけでやり遂げることができるさまざまな方法に焦点を当てています。

関連する問題