リストをリストのリストにグループ化する素晴らしい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]]
射影自体は気にしません。一部の要素が等しい場合、これらは同じサブリストに含まれる必要があります。
私は基本的にpython haskell関数に相当するものを探しています GHC.Exts.groupWith
:
Prelude> import GHC.Exts
Prelude GHC.Exts> groupWith (`mod` 3) [0..7]
[[0,3,6],[1,4,7],[2,5]]
標準ライブラリのitertools
モジュールには、必要な処理を実行する必要がある groupby()
関数が含まれています。
groupby()
への入力は、各グループを1回だけ生成するようにグループキーで並べ替える必要がありますが、並べ替えに同じキー関数を使用するのは簡単です。したがって、主要な関数(射影)が数値が偶数であるかどうかを調べている場合、次のようになります。
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]]
このバージョンは標準のPython機能のみを使用しますが、おそらく100.000を超える値を処理している場合は、pandas(@ ayhanの回答を参照)を調べる必要があることに注意してください)
並べ替える必要はありません。
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]
パンダ バージョンは次のようになります:
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]])
compress
from itertools
を使用した1つのアプローチを次に示します。
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]]