2017-10-16 16 views
0

すべての値とすべてを見つけました。ソートを試みましたが、一緒にではなく別々にソートしました。私は年単位でソートしたいが、成績はちょうど年の値に従うべきだ。しかし、私がソート(年)をするとき、それはグレードをそのまま残して、年を並べ替えるだけです。2つの異なる配列から値をソート

Year,Grade 
2000,84 
2001,34 
2002,82 
2012,74 
2008,90 

など:

ファイルを開くと、 は、それは私のようなものを与えるだろう。だから私は平均とすべてを計算した。ソートなし

years, average_grades = [],[] 
avg = [] 
d = {} 

with open(file,'r') as f: 
    next(f) 
    for line in f: 
     year, grade = (s.strip() for s in line.split(',')) 
     if year in d: 
      d[year][0] += int(grade) 
      d[year][1] += 1 
     else: 
      d[year] = [int(grade),1] 

    for year, grades in d.items(): 
     years.append(str(year)) 
     average_grades.append(float(grades[0])/grades[1]) 

    return years, average_grades 

、それは私にこれに類似を与える:

2001 74.625 
2006 72.241 
2012 70.875 
2017 69.1981 
2005 72.5 
2008 71.244 
2014 73.318 
2004 72.1 
2007 72.88 
2000 73.1 

With years.sort(), it would give me similar to this: 
2000 74.625 
2001 72.241 
2002 70.875 
2003 69.1981 
2004 72.5 
2005 71.244 
2006 73.318 
2007 72.1 

ので、ソートはわずか数年のために働くだろうが、成績のためにそれを行うことはありません。 この問題は長い間私を悩ませています。私はパンダを使うつもりはない。

+0

あなたは、私が例のデータを提供したデータ –

+0

の例を投稿することができます。 – Mayjunejuly

+0

問題は、2つの_independent_データ構造体を返すことです。返された 'years'と' average_grades'は、それらを返すときには関係しません。 – Unapiedra

答えて

0

あなたは、returnステートメントの前に次の行を追加します:

years, average_grades = zip(*sorted(zip(years, average_grades), key=lambda p: p[0])) 

これは何をしますか?

は、iterables yearsaverage_gradesの各要素をタプルの配列としてまとめるようにpythonに指示します。

sorted(..., key=lambda p: p[0])は、ペアで動作していることを除いて、sortedユーティリティですが、ペアをどのようにソートするかを知る必要があります。そこで、「最初の部分を見てください」と言うラムダ関数を渡します。

外部zip(*...)は、タプルのリストであるソート済みの結果を2つのリストに変換します。 *は、リストを引数の束として扱うように指示するので、あなたはペアで渡されてzipになります。 zipは任意の数のタプル引数をとり、それらをその構成部分に分割します。この場合、それは10のペアを取り、それをそれぞれ長さ10の2つのタプルに分割しています。

イテラブルの長さが同じであれば、これを一緒に並べ替える「基本的な」メカニズムです。

+0

素晴らしい答えではありません:OPが投稿されたコードを管理している場合、 '(年、年齢)'のタプルをまとめておく方がはるかにクリーンです。その後、並べ替え、次に解凍します。しかし、downvoteはありません。 – Unapiedra

+0

変数を別々に維持し、それらを圧縮することの唯一の違いは、zipの使用です。 2つの別々のデータセットがある実際の例がたくさんあります。 @Unapiedra、Stack Overflowの目標は、将来のユーザーのための知識のリポジトリを作成することです。この例では、2つのリストを分離しない方が優れた解決方法であると主張することは有効です。この特定のインスタンスのために提供する実装のために、将来の質問者を助けるために十分な情報を提供する回答が「大きな答えではない」と主張することは有効ではありません。 –

1

zipを使用して、tuple、次にsortとして結合します。

>>> for ele in sorted(mix): 
     print(ele[0],ele[1]) 

1 0.7 
2 0.1 
2 0.4 
3 0.1 
4 0.2 

2ため、0.10.4の二つの値があることと、それを処理する:あなたのために

>>> y = [3, 2, 4, 1, 2] 
>>> g = [0.1, 0.4, 0.2, 0.7, 0.1] 

>>> mix = list(zip(y,g)) 
>>> mix 
=> [(3, 0.1), (2, 0.4), (4, 0.2), (1, 0.7), (2, 0.1)] 

>>> sorted(mix) 
=> [(1, 0.7), (2, 0.1), (2, 0.4), (3, 0.1), (4, 0.2)] 

#print yearと次のgradesがより優先されます。

0

私はそう、この例が参考になることを願っ:

years = [2001,2000,2002] 
average_grades = [5,10,15] 
result = zip(years,average_grades) 
for item in sorted(result, key=lambda x: x[0]): 
    print('{} {}'.format(*item)) 
#2000 10 
#2001 5 
#2002 15 
0

代替ソリューションは、結果を取り、それらを一緒にビュンています。あなたはファイルの読書をコントロールしているように見えますが、私は代わりにに年月と年齢を分割しないことをお勧めします

これは後で2つのリストをzipで結合するよりも簡単です。あなたはif year in dブロックを避けるためにdefaultdictを使用することができます

years, average_grades = [],[] 
avg = [] 
d = {} 

with open(file,'r') as f: 
    next(f) 
    for line in f: 
     year, grade = (s.strip() for s in line.split(',')) 
     if year in d: 
      d[year][0] += int(grade) 
      d[year][1] += 1 
     else: 
      d[year] = [int(grade),1] 

# Iterator-Expression to convert 'd' dictionary into list of tuples. 
# Puts (year, average grade) into a new list. 
year_grade = [(year, float(grade_tuple[0])/grade_tuple[1]) \ 
       for year, grade_tuple in d.items()] 

# Sorting is optional, if you return the list of tuples. 
# Use 'key=lambda ...' to sort over the year (the first element of the tuple). 
# Technically, specyfing the 'key' is not necessary as the default would be 
# to sort over the first element first. 
year_grade.sort(key=lambda x: x[0]) 

return year_grade 
# Alternatively, return the list of tuples as a list of two tuples: years, grades 
return zip(*year_grade) 

その他の改善

from collections import defaultdict 

d = defaultdict(lambda: [0, 0]) 

with open(fname,'r') as f: 
    next(f) 
    for line in f: 
     year, grade = (s.strip() for s in line.split(',')) 
     d[year][0] += int(grade) 
     d[year][1] += 1 

    def avg(t): 
     return float(t[0])/t[1] 
    year_grade = [(y, avg(g)) for y, g in d.items()] 
    year_grade.sort() 

    return zip(*year_grade) # Python3: tuple(zip(*year_grade)) 
関連する問題