2016-06-01 3 views
3

リストをリストのグループにグループ化する素晴らしい方法はありますか?内部リストのそれぞれには、同じ投影を持つ要素機能としてのユーザーですか?Python:リストを投影値の等価でサブリストにグループ化する

例:

>>> x = [0, 1, 2, 3, 4, 5, 6, 7] 
>>> groupby(x, projection=lambda e: e % 3) 
[[0, 3, 6], [1, 4, 7], [2, 5]] 

私はそれはいくつかの要素のために等しい場合、これらは同じサブリストで終わるしなければならないだけであること、投影自体を気にしないでください。

私は基本的にHaskellの機能GHC.Exts.groupWithのPythonの同等を探しています:

Prelude> import GHC.Exts 
Prelude GHC.Exts> groupWith (`mod` 3) [0..7] 
[[0,3,6],[1,4,7],[2,5]] 

答えて

6

標準ライブラリでitertoolsモジュールは、あなたが欲しいものを行う必要がありgroupby()機能が含まれています。

groupby()への入力は、各グループを1回だけ生成するためにグループキーでソートする必要がありますが、ソートには同じキー機能を使用するのが簡単です。あなたは多分100.000以上を扱っている場合は、このバージョンでは唯一、標準のPythonの機能を使用しながら、ということ

from itertools import groupby 
x = [0, 1, 2, 3, 4, 5, 6, 7] 

def projection(val): 
    return val % 3 

x_sorted = sorted(x, key=projection) 
x_grouped = [list(it) for k, it in groupby(x_sorted, projection)]  
print(x_grouped) 

[[0, 3, 6], [1, 4, 7], [2, 5]] 

注:お使いのキー機能(投影)数が偶数であるかどうかを見ているのであれば、それは次のようになります。あなたはパンダを調べるべきです(@ ayhanの答えを参照してください)

4

並べ替える必要はありません。

from collections import defaultdict 

def groupby(iterable, projection): 
    result = defaultdict(list) 
    for item in iterable: 
     result[projection(item)].append(item) 
    return result 

x = [0, 1, 2, 3, 4, 5, 6, 7] 
groups = groupby(x, projection=lambda e: e % 3) 
print groups 
print groups[0] 

出力:ここ

defaultdict(<type 'list'>, {0: [0, 3, 6], 1: [1, 4, 7], 2: [2, 5]}) 
[0, 3, 6] 
1

一つのアプローチが使用しているcompressitertoolsから:pandasバージョンは次のようになります

from itertools import compress 
import numpy as np 

L = [i %3 for i in x] 

[list(compress(x, np.array(L)==i)) for i in set(L)] 
#[[0, 3, 6], [1, 4, 7], [2, 5]] 
+0

'np.array(L)'は、すべてのキー(予測)に対して計算する必要がないように、おそらく一時変数に格納する必要があります。 –

2

import pandas as pd 
x = [0, 1, 2, 3, 4, 5, 6, 7] 
pd.Series(x).groupby(lambda t: t%3).groups 
Out[13]: {0: [0, 3, 6], 1: [1, 4, 7], 2: [2, 5]} 

または

pd.Series(x).groupby(lambda t: t%3).groups.values() 
Out[32]: dict_values([[0, 3, 6], [1, 4, 7], [2, 5]]) 
関連する問題