2

私のコードはおそらく遅いです:

onlyPositives = map ( (lambda mylist: [elem for elem in mylist if elem > 0]) , myintlist )

それを行うための速い方法は何ですか?(サイズ 50 int の 100 万個のサブ リストの場合)。

4

3 に答える 3

3

a を使用する代わりに関数を個別に定義し、 の代わりにlambdaリスト内包表記を使用しますmap()

def func(mylist):
    return [elem for elem in mylist if elem > 0]

onlyPositives = [func(e) for e in myintlist]

以下のコメントに基づいて、このコードのさまざまなバージョンをプロファイリングする価値があると思いmap()ますfilter().

ただし、100 万個のサブリストがある場合、できることは限られています。

于 2013-11-08T22:36:06.503 に答える
2

まず、データ構造とアルゴリズムを改善できないと仮定します。

その場合、アルゴリズムの実装に問題はありません。Simeon Visser が指摘しているように、オーバーヘッドを少し下げる方法はあるかもしれませんが、そこで達成できることは限られています。

しかし、Python を高速化する以上のことを望むなら、次の 3 つの大きな選択肢があります。

  • コードを並列化します。4 つのプロセスを実行し、それぞれが元のリストの 4 分の 1 を変換します。ほぼ 4 倍の速度になるはずです。
  • NumPy や Pandas などを使用して、コードをベクトル化します。単純な算術演算 (> 0 など) を実行している場合、Python のループ オーバーヘッドは実際の作業よりも 10 倍遅くなる可能性があるため、10 倍のスピードアップが得られます。(言うまでもなく、これはごまかしです。あなたのデータ構造は変更できないと思っていたので、それを変更しました。しかし、変換が些細で明白なものである場合、たとえば、リストとして表された固定形状の 2D 配列から)として表される固定形状の 2D 配列へのリストの変換はndarray、ごまかす価値があります。)
  • Python ではなく Cython で記述するか、CPython ではなく PyPy で実行して、コードをコンパイルします。一般に、これにより NumPy よりも高速化が少し遅くなります (そして、高速化は事前にさらに予測できません) が、作業も大幅に少なくなります。
于 2013-11-08T22:41:53.517 に答える
0

ここにいくつかの方法があります - 最初のものはあなたが提供したものです。ところで、CPython では関数呼び出しに比較的大きなオーバーヘッドがあります。速度を上げるには、pypy、numba、または cython を使用するとよいでしょう。飾り気のない CPython を使い続けたい場合は、lambda と def を使用すると速度が低下します。

#!/usr/bin/python3

myintlist = [ [ 1, 2, 3, -1, -6, 0 ], [ 5, 6, 7, -4, 2, -6, 3, -6, 0, 10] ]
onlyPositives = map ((lambda mylist: [ elem for elem in mylist if elem > 0 ]), myintlist)
print(onlyPositives)

onlyPositives2 = []
for input_sublist in myintlist:
    output_sublist = (element for element in input_sublist if element > 0)
    onlyPositives2.append(output_sublist)
print(onlyPositives2)

# You could change the list comprehension to another generator expression if you want
onlyPositives3 = ([element for element in input_sublist if element > 0] for input_sublist in myintlist)
print(onlyPositives3)
于 2013-11-08T22:49:19.493 に答える