2017-09-29 1 views
-2

次のように私は2つのリストを持っている:重複する要素を見つけてリストから削除するにはどうすればよいですか?

name =[A, B , C , D , E , F ] 
cls=[1, 2 , 3 , 2 , 4 , 1 ] 
score=[0.1, 0.2 , 0.5 , 0.3 , 1 , 0.8 ] 

Aがクラス1とそのスコア0.1に属している、ようにBがクラス2に属し、そのスコアが0.2であり、そして意味します。

オブジェクトが同じクラスを持つメソッドを探していて、そのスコアがクラス内の別のオブジェクト(cls)よりも小さい場合、そのオブジェクトを削除します。だから、私の予想結果は

name =[C , D , E , F ] 
cls =[3 , 2 , 4 , 1 ] 
score=[0.5 ,0.3 , 1 , 0.8 ] 

nameclsscoreであるリスト型です。どのように私はそれをPythonで実装できますか?おかげ

は、これは、Pythonの予約キーワードですので、あなたが変数名としてclassを使用することはできません、私が何をしたか

name_clean=[] 
cls_clean=[] 
score_clean=[] 
for i in range(len(cls)-1): 
    cls_i=cls[i] 
    max_index = -1 
    for j in range(i+1,len(cls)): 
     cls_j = cls[j] 
     if (cls_i==cls_j): 
      if (score[i]<=score[j]): 
       max_index=j 
      else: 
       max_index=i 
    if (max_index>=0): 
     name_clean.append(name[max_index]) 
     cls_clean.append(cls[max_index]) 
     score_clean.append(score[max_index]) 
    else: 
     name_clean.append(name[i]) 
     cls_clean.append(cls[i]) 
     score_clean.append(score[i]) 
+2

こんにちは、これはコード補完サービスではありません。質問をする方法を読んでください:[問題を説明して**それを解決するためにこれまでに何がなされているか**】(https://stackoverflow.com/help/on-topic) – danihp

+0

私はこの質問を閉じるために投票していますOPは他の人に自分の仕事を依頼しているから話題にはならない。 – danihp

+0

2つのforループを使って試しましたが、成功しませんでした。したがって、私はここで尋ねます。なぜそれは近いですか? – user8264

答えて

2

注意です。

3つのリストを使用する代わりに、namedtupleまたは表を含む1つのリストを使用することを検討します。 pandas.DataFrame。しかし

あなたは3つのリストとしてそれを持っているので、私はこのようにそれを行うだろう:

各クラスの最高のスコアを取得し、辞書

highest_scores = {} 
for c, s in zip(cls, score): 
    current_max = highest_scores.get(c, None) 
    if current_max is None or current_max < s: # not present or smaller 
     highest_scores[c] = s 

に保管しては、再度リストを反復処理し、

new_name = [] 
new_cls = [] 
new_score = [] 
for n, c, s in zip(name, cls, score): 
    if s == highest_scores[c]: 
     new_name.append(n) 
     new_cls.append(c) 
     new_score.append(s) 

います:のみ、そのクラスのために保存されたスコアに等しいスコアを持っているものを残し

>>> new_name 
['C', 'D', 'E', 'F'] 
>>> new_cls 
[3, 2, 4, 1] 
>>> new_score 
[0.5, 0.3, 1, 0.8] 

これは、各クラスについてすべて「最高スコア」を維持することに注意してください。同じクラスと同じスコアを持つ場合、これは両方を維持します。これを修正するには、最初に見つかったときにすぐに辞書からキーを削除することができます。

+0

パーフェクト!わかった。ありがとうございます – user8264

+0

"3つのリストを使うのではなく、名前付きタプルやテーブル" =>を含む1つのリストを使うか、単純なタプルを使うことを検討します... –

+0

@brunodesthuilliersそう、リスト/ dicts/customクラスです。私はあなたが属性の名前を失わない最も簡単な選択肢を示したかったのです。 – MSeifert

1

適切なデータ構造を使用すると、多くの役に立ちます。あなたのケースでは、あなたがclassしてデータを再グループ化したい:

names = ["A", "B", "C", "D", "E", "F"] 
classes = [1, 2 , 3 , 2 , 4 , 1] 
scores = [0.1, 0.2 , 0.5 , 0.3 , 1 , 0.8] 

byclasses = defaultdict(list) 
for name, class_, score in zip(names, classes, scores): 
    byclasses[class_].append((score, name)) 

print byclasses 

この段階で何を得ることです:

{1: [(0.1, 'A'), (0.8, 'F')], 
2: [(0.2, 'B'), (0.3, 'D')], 
3: [(0.5, 'C')], 
4: [(1, 'E')] 
} 

今、あなただけ(彼らがソートされますリストのそれぞれをソートする必要がありスコア昇順に)、あなたに(クラス、スコア、名前)タプルのリストを与えるスコアが最も高いものになる、各リストの最後の項目()

cleaned = [((k,) + sorted(v)[-1]) for k, v in byclasses.items()] 
print cleaned 

保つ:

[(1, 0.8, 'F'), (2, 0.3, 'D'), (3, 0.5, 'C'), (4, 1, 'E')] 

と - あなたの代わりにタプルのリストの3つのリストを持つ上で主張すれば - つの新しいリストに結果を解凍します。

cnames, cclasses, cscores = (list(c) for c in zip(*cleaned)) 
print cnames, cclasses, cscores 

、ここで私たちは、次のとおりです。

[1, 2, 3, 4] [0.8, 0.3, 0.5, 1] ['F', 'D', 'C', 'E'] 
1

問題を2つの異なるステップに分割します。

  1. 項目の各クラスのスコアと地図
  2. それをストアは異なるクラスを見つける最大スコア

注意セットの使用()、

name = ['A', 'B', 'C', 'D', 'E', 'F'] 
cls = [1, 2, 3, 2, 4, 1] 
score = [0.1, 0.2, 0.5, 0.3, 1, 0.8] 

# find largest score for each class 
max_class_scores = {} # key is class, value is max score 
for c in set(cls): 
    # contains max score for a class 
    max_class_scores[c] = max(s for (i,s) in enumerate(score) if cls[i]==c) 

new_name = [] 
new_cls = [] 
new_score =[] 
for n,c,s in zip(name,cls,score): 
    max_score = max_class_scores[c] 
    if s == max_score : # only process where the current record is max for the class 
     new_name.append(n) 
     new_cls.append(c) 
     new_score.append(s) 

print(new_name,new_cls,new_score) 
1
from itertools import groupby 
from operator import itemgetter 

name=['A','B','C','D','E','F'] 
cls=[1,2,3,2,4,1] 
score=[0.1,0.2,0.5,0.3,1,0.8] 

f=itemgetter(1) 
g=itemgetter(2) 
groups=groupby(sorted(zip(name,cls,score), key=f), key=f) 

name, cls, score = zip(*map(lambda x: max(x, key=g), ((item for item in data) for (key, data) in groups))) 
に対応する項目のみを含む新しいリストを作成します
関連する問題