2017-10-13 7 views
1

私はパンダが初めてです。私は最適化したいコードを書いたが、どうしたらよいかわからない。私は、「適用」とパンダベクトル化の両方が「iterrows」より速いという事実を認識していますが、同じ目標を達成するためにそれらをどのように使用するかはわかりません。 iterrowsは 'for'ループに似ているので私にとっては簡単なので、私はそれに慣れています。あなたが見ることができるように、2ネストされた 'iterrows' ループがパンダのコードを最適化する: 'iterrows'と他のアイデアを交換する

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
from sklearn.metrics import mean_squared_error 
from scipy.spatial.distance import euclidean 
data = pd.read_csv(r'C:\temp\train.txt') 

def group_df(df,num): 
    ln = len(df) 
    rang = np.arange(ln) 
    splt = np.array_split(rang,num) 
    lst = [] 
    finel_lst = [] 
    for i,x in enumerate(splt): 
     lst.append([i for x in range(len(x))]) 
    for k in lst: 
     for j in k: 
      finel_lst.append(j) 
    df['group'] = finel_lst 
    return df 
def KNN(dafra,folds,K,fi,target):   
    df = group_df(dafra,folds) 
    avarge_e = [] 
    for i in range(folds): 
     train = pd.DataFrame(df.loc[df['group'] != i]) 
     test = pd.DataFrame(df.loc[df['group'] == i]) 
     test.loc[:,'pred_price'] = np.nan 
     test.loc[:,'rmse'] = np.nan 
     train.loc[:,'dis'] = np.nan 
     train = train.reset_index() 
     test = test.reset_index() 
     for index,row in test.iterrows(): 
      for index2,row2 in train.iterrows(): 
       train.loc[index2]['dis'] = euclidean(row2[fi],row[fi]) 

: はここに私のコードです。上部には1つの小さな 'for'ループもあります。 このコードのアイデアは、テストのすべての行と列の各行との間のユークリッド距離を割り当てることです。しかし、テストは 'for'ループによって変更されるため、最終的に元のDataFrameのすべてに追加されます。ここ

データのbegginingある:

Id MSSubClass MSZoning LotFrontage LotArea Street Alley LotShape \ 
0 1   60  RL   65.0  8450 Pave NaN  Reg 
1 2   20  RL   80.0  9600 Pave NaN  Reg 
2 3   60  RL   68.0 11250 Pave NaN  IR1 

    LandContour Utilities ...  PoolArea PoolQC Fence MiscFeature MiscVal 
\ 
0   Lvl AllPub ...   0 NaN NaN   NaN  0 

1   Lvl AllPub ...   0 NaN NaN   NaN  0 

2   Lvl AllPub ...   0 NaN NaN   NaN  0 

    MoSold YrSold SaleType SaleCondition SalePrice 
0  2 2008  WD   Normal  208500 
1  5 2007  WD   Normal  181500 
2  9 2008  WD   Normal  223500 

このコードをoptimaing [3行×81列]

任意のアイデアは歓迎されるだろう。ありがとうございました。私はあなたの問題には、次の2つの可能な解決策を示唆している

+0

はあなたが試験データを提供することができます: は、あなたが新しいデータフレームにdfを元のインデックスに渡すことができ、元のインデックスを維持するために、 ? –

+0

私のDataFrameの最初のfue行ですか? –

+0

はい、アーカイブする内容は –

答えて

0

-Using scipys distance_matrix

- 書き込み独自のnumpyの機能は

scipyのダウンロードソリューションはまっすぐ前方にある:

import scipy 
import numpy as np 

point_vector_1 = np.random.random((10000,2)) 
point_vector_2 = np.random.random((1000,2)) 
distance_matrix = scipy.spatial.distance_matrix(point_vector_1, point_vector_2) 

numpyでは、外側のufuncを使用して独自の関数をコーディングすることができます。 np.subtract.outerは、外積と同様に2つのベクトルから行列を与え、乗算と同様に与えます。

def euclidean_distance_matrix(vector_1, vector_2): 
    dis_dim_1 = np.subtract.outer(vector_1.T[0], vector_2.T[0])**2 
    dis_dim_2 = np.subtract.outer(vector_1.T[1], vector_2.T[1])**2 
    euclidean = np.sqrt(dis_dim_1+dis_dim_2) 
    return euclidean 

distance_matrix_2 = euclidean_distance_matrix(point_vector_1, point_vector_2) 

タイミング:

%timeit scipy.spatial.distance_matrix(point_vector_1, point_vector_2) 
382 ms ± 8.56 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 
%timeit euclidean_distance_matrix(point_vector_1, point_vector_2) 
150 ms ± 1.33 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 

編集:

dist_array = euclidean_distance_matrix([df1['lat'], df1['long']], [df2['lat'], df2['long']]) 
df_dist = pd.DataFrame(dist_array, index=df1.index, columns=df2.index) 
+0

あなたの提案をありがとうございます。それは良い解決策です。私自身のfuncを書くことはDataFrameのインデックスとラベルを失うので、新しい行列のどのベクトルが元のベクトルのどの列か行であるかを知ることはできません。それを防ぐ方法はありますか? –

関連する問題