2016-06-22 3 views
0

から一定の条件を満たし、最後の発生を抽出する方法を、私はリストとして、次のデータを持っている:Pythonの - たとえば、リスト

'A''B'、および 'C'のための今
l = [['A', 'aa', '1', '300'], 
    ['A', 'ab', '2', '30'], 
    ['A', 'ac', '3', '60'], 
    ['B', 'ba', '5', '50'], 
    ['B', 'bb', '4', '10'], 
    ['C', 'ca', '6', '50']] 

、私が取得したいです彼らの最後の出現、すなわち:

[['A', 'ab', '3', '30'], 
['B', 'bb', '4', '10'], 
['C', 'ca', '6', '50']] 

またはさらに、これらの発生、すなわちで3列目:

['3', '4', '6'] 

現在、私はこれに対処する方法は、次のとおりです。

import pandas as pd 
df = pd.DataFrame(l, columns=['u', 'w', 'y', 'z']) 
df.set_index('u', inplace=True) 
ll = [] 
for letter in df.index.unique(): 
    ll.append((df.ix[letter, 'y'][-1])) 

はその後、私%timeit、それは示しています。これを行う方法があるかどう

>> The slowest run took 27.86 times longer than the fastest. 
>> This could mean that an intermediate result is being cached. 
>> 1000000 loops, best of 3: 887 ns per loop 

はちょうど私のコードよりも少ない時間を使って不思議?ありがとう!私はあなたの質問を理解してわからないにもかかわらず

+0

あなたが現在持っている非効率な方法は何ですか? – jonrsharpe

+3

なぜ「A」の最後のオカレンスは2番目のもので、3番目のアレイではないのですか? –

+0

あなたのリストで逆の使い方をしてください - [条件に一致する反復可能文字から最初の項目を取得する最も良い方法は何ですか?](http://stackoverflow.com/questions/2361426/what-is-the- –

答えて

2
l = [['A', 'aa', '1', '300'], 
    ['A', 'ab', '2', '30'], 
    ['A', 'ac', '3', '60'], 
    ['B', 'ba', '5', '50'], 
    ['B', 'bb', '4', '10'], 
    ['C', 'ca', '6', '50']] 

import itertools 
for key, group in itertools.groupby(l, lambda x: x[0]): 
    print key, list(group)[-1] 

に「C」のマッピングを取得しますすべて。リストが事前にサブリストの最初の要素によってソートされていると仮定します。

def tidy(l): 
    tmp = [] 
    prev_row = l[0] 

    for row in l: 
     if row[0] != prev_row[0]: 
      tmp.append(prev_row) 
     prev_row = row 
    tmp.append(prev_row) 
    return tmp 

を、これは速いitertools.groupbyよりはtimeit試験で〜5倍である:リストがソートされている場合

を通じて、一度の実行では十分なはずです。デモンストレーション:https://repl.it/C5Af/0

[編集:OPはすでに道速い可能性がある、彼らはすでにGROUPBYするパンダを使用していると言って自分の質問を更新しました]

+0

申し訳ありませんが、これを誤って編集したため、削除できないようです!可能であれば削除してもよろしいですか、これを私の答えに今追加しました! –

+0

@NilsGudatそれは大丈夫です、私は編集を拒否しました。私は 'itertools.groupby'アプローチがGroupInfoオブジェクトと新しいリストを構築しているので遅くなると思っています。リストをソートしていると仮定して、リストを実行することでこれを行うことは可能です。私はそれがかなりPythonicであり、それが何をしているのかをより明確に表現していると思います。 – TessellatingHeckler

1

、ここにあなたが何ができるかです:Aの最後に出現するが、第三ではないように思わとして出力は、[3,4,6]ある

li = [l[i][0] for i in range(len(l))] 
[l[j][2] for j in [''.join(li).rfind(i) for i in set(li)]] 

に留意されたいです。 2番目の配列。

編集(あなたがしようとしたものを「良い」としての資格だこと言わないが)あなたはパフォーマンスについて非常に心配思えるよう:

%timeit li = [l[i][0] for i in range(len(l))] 
%timeit [l[j][2] for j in [''.join(li).rfind(i) for i in set(li)]] 
>> 1000000 loops, best of 3: 1.19 µs per loop 
>> 100000 loops, best of 3: 2.57 µs per loop 

%timeit [list(group)[-1][2] for key, group in itertools.groupby(l, lambda x: x[0])] 
>> 100000 loops, best of 3: 5.11 µs per loop 

だから、リスト内包がよりわずかに速いようですitertools(私はベンチマークの専門家ではなく、itertoolsを実行するためのより良い方法があるかもしれませんが)。

0

A-非常に-Python的ではないアプローチ:(ニルスのソリューションは、最もニシキヘビであることに注意してください - リストの内包表記を使用して)

def get_last_row(xs,q): 
    for i in range(len(xs)-1,-1,-1): 
     if xs[i][0] == q: 
      return xs[i][2] 

def get_third_cols(xs): 
    third_cols = [] 
    for q in ["A","B","C"]: 
     third_cols.append(get_last_row(xs,q)) 
    return third_cols 

print get_third_cols(xs) 

それはあなたが最後に出現することにより、どのような意味だ場合、これは['3', '4', '6']を印刷します。あなたがであなたの条件を説明していないため

1

{l[0]: l[2] for l in vals}はあなたの「A」、「B」、および彼らの最後の値が「効率性」にノーコメントで

+0

こんにちは、ちょっとあなたのコードを説明してもらえますか?私はそれを使って結果を得る方法をあまり理解していません。ところで、「vals」は何ですか?ありがとう! – Map

+0

'vals'はあなたの入力(あなたのリストのリスト)です。コード自体については、dictの内包表記を読んで、その動作を確認します。 – acushner

+0

辞書の代わりに '['3'、 '4'、 '6']'のようなリストを返すことは可能でしょうか? – Map

0

これは、任意のキー/値の場所に一般ます。出力はで、最初のキーが確認された順にになります。

%timeit getLast(l,0,2) 

は与えるため、出力の順序は、出力値がそれをタイミング今

import operator 

l = [['A', 'aa', '1', '300'], 
    ['A', 'ab', '2', '30'], 
    ['A', 'ac', '3', '60'], 
    ['B', 'ba', '5', '50'], 
    ['B', 'bb', '4', '10'], 
    ['C', 'ca', '6', '50']] 

def getLast(data, key, value): 
    f = operator.itemgetter(key,value) 
    store = dict() 
    keys = [] 
    for row in data: 
     key, value = f(row) 
     if key not in store: 
      keys.append(key) 
     store[key] = value 
    return [store[k] for k in keys] 

に観察されたことの順序であることを調整することは難しいことではないでしょうなります

The slowest run took 9.44 times longer than the fastest. This could mean that an intermediate result is being cached 
100000 loops, best of 3: 2.85 µs per loop 

出力機能:

['3', '4', '6'] 
関連する問題