2016-06-12 5 views
2

私はあまりにも遅いfolowing最小限のコードを持っています。私が必要とする1000行の場合、約2分かかります。私はそれをより速く走らせる必要があります。Python:高速サブセッティングとループのデータフレーム

import numpy as np 
import pandas as pd 

df = pd.DataFrame(np.random.randint(0,1000,size=(1000, 4)), columns=list('ABCD')) 
start_algorithm = time.time() 
myunique = df['D'].unique() 
for i in myunique: 
    itemp = df[df['D'] == i] 
    for j in myunique: 
     jtemp = df[df['D'] == j] 

私はnumpyのは、列の特定の値「D」のために、それは私が、元のデータフレーム(またはnumpyの中のアレイ)の一部を残しておきたいというはるかに高速に実行しますが、心に留めておくことができますことを知っています。どのように性能を向上させることができますか?

+0

を(http://stackoverflow.com/help/mcve)質問をするとき。 _pandas_の質問の場合は、サンプルの_input_と_output_データセット(CSV/dict/JSON/Pythonコードの形式で_7行〜_ text_です)を入力して、回答をコーディングする際に使用できます。これは、「あなたのコードは私のために働いていない」、あるいは「自分のデータでは動かない」などのような_situations_を避けるのに役立ちます。 – MaxU

+1

あなたは何をしたいのかはっきりしません... – MaxU

+0

私はしませんデータフレームの行を通して単純なループが必要です。それ以外の場合は簡単にnumpyで実装できます。元のデータフレームのサブセットを生成するolumn 'D'のユニークな値を使用するループが必要です。 numpyでは、2次元配列のすべての要素を繰り返し処理し、列 'D'に同じ値の行を格納する必要があります。実際のデータはありません。そのため、私はデータフレームにランダムな値を与えました。 – ilias

答えて

3

サブデータフレームdf[df['D'] == i]を複数回は計算しないでください。元のコードはlen(myunique)**2回計算します。代わりに、これをそれぞれi(すなわち合計でlen(myunique)回)ごとに1回計算し、結果を保存して後でそれらをペアにすることができます。例えば、コメントに関しては

groups = [grp for di, grp in df.groupby('D')] 
    for itemp, jtemp in IT.product(groups, repeat=2): 
     pass 

import pandas as pd 
import itertools as IT 
df = pd.DataFrame(np.random.randint(0,1000,size=(1000, 4)), columns=list('ABCD')) 

def using_orig(): 
    myunique = df['D'].unique() 
    for i in myunique: 
     itemp = df[df['D'] == i] 
     for j in myunique: 
      jtemp = df[df['D'] == j] 

def using_groupby(): 
    groups = [grp for di, grp in df.groupby('D')] 
    for itemp, jtemp in IT.product(groups, repeat=2): 
     pass 

In [28]: %timeit using_groupby() 
10 loops, best of 3: 63.8 ms per loop 
In [31]: %timeit using_orig() 
1 loop, best of 3: 2min 22s per loop 

は、私は簡単にこんにちは」= 1またはプリントでITEMPとjtempを置き換えることができます"それで無視してください

上記の答えは、itempjtempをより効率的に計算する方法について説明しています。 itempjtempが実際の計算の中心でない場合は、を実際に計算したいものをとよく理解して、できるだけ速く計算する方法を提案する必要があります。

+0

私はあなたの魔法の水晶のボールを持っていたと思う...;) – MaxU

+1

itempとjtempについての私のコメントは(私がその時に思ったように)ユニークな私はunutbuの驚くべき答えから見ることができるように、私は明らかに間違っていたので、私はstackoverflowのメンバーに多少の誤った案内をすることをお詫びします。あなたの答えはうまくいきます。あなたの時間と貢献に感謝します。 – ilias

0

ここ"D"カラムからユニークな要素に基づいてグループを形成するために、ベクトル化アプローチだ -

# Sort the dataframe based on the sorted indices of column 'D' 
df_sorted = df.iloc[df['D'].argsort()] 

# In the sorted dataframe's 'D' column find the shift/cut indces 
# (places where elements change values, indicating change of groups). 
# Cut the dataframe at those indices for the final groups with NumPy Split. 
cut_idx = np.where(np.diff(df_sorted['D'])>0)[0]+1 
df_split = np.split(df_sorted,cut_idx) 

サンプル試験

1]はランダム要素とサンプルデータフレームフォーム:

>>> df = pd.DataFrame(np.random.randint(0,100,size=(5, 4)), columns=list('ABCD')) 
>>> df 
    A B C D 
0 68 68 90 39 
1 53 99 20 85 
2 64 76 21 19 
3 90 91 32 36 
4 24 9 89 19 

2]元のコードを実行し、結果を印刷します。

>>> myunique = df['D'].unique() 
>>> for i in myunique: 
...  itemp = df[df['D'] == i] 
...  print itemp 
... 
    A B C D 
0 68 68 90 39 
    A B C D 
1 53 99 20 85 
    A B C D 
2 64 76 21 19 
4 24 9 89 19 
    A B C D 
3 90 91 32 36 

3]提案されたコードを実行し、結果を印刷する:] [、最小完全、かつ検証例を提供するために、常に試し

>>> df_sorted = df.iloc[df['D'].argsort()] 
>>> cut_idx = np.where(np.diff(df_sorted['D'])>0)[0]+1 
>>> df_split = np.split(df_sorted,cut_idx) 
>>> for split in df_split: 
...  print split 
... 
    A B C D 
2 64 76 21 19 
4 24 9 89 19 
    A B C D 
3 90 91 32 36 
    A B C D 
0 68 68 90 39 
    A B C D 
1 53 99 20 85