2017-02-08 5 views
0

主な問題array2にない配列1の要素を取得する

特定の配列内の異なる配列にはない要素を取得する、より優れた方法です。これは私が持っているものです。

idata = [np.column_stack(data[k]) for k in range(len(data)) if data[k] not in final] 
idata = np.vstack(idata) 

私の興味はパフォーマンスです。私dataは(X、Y、Z)サイズの配列(×3 7000)であると私gdataは、私が上で働いている前文

(11000×2)

の(X、Y)の配列であります各オクタントの点(+)に最も​​近い点(+)のn個(例えば8個)を見つける。これは私のポイント(+)がわずか64(8分の1)に減少することを意味します。そして、それぞれgdataについては、dataに見つからない要素を保存します。

enter image description here

import tkinter as tk 
from tkinter import filedialog 
import pandas as pd 
import numpy as np 
from scipy.spatial.distance import cdist 
from collections import defaultdict 

root = tk.Tk() 
root.withdraw() 
file_path = filedialog.askopenfilename() 
data = pd.read_excel(file_path) 
data = np.array(data, dtype=np.float) 
nrow, cols = data.shape 

file_path1 = filedialog.askopenfilename() 
gdata = pd.read_excel(file_path1) 
gdata = np.array(gdata, dtype=np.float) 
gnrow, gcols = gdata.shape 

N=8 
delta = gdata - data[:,:2] 
angles = np.arctan2(delta[:,1], delta[:,0]) 
bins = np.linspace(-np.pi, np.pi, 9) 
bins[-1] = np.inf # handle edge case 
octantsort = [] 

for j in range(gnrow):  
    delta = gdata[j, ::] - data[:, :2] 
    angles = np.arctan2(delta[:, 1], delta[:, 0]) 
    octantsort = [] 

    for i in range(8): 
     data_i = data[(bins[i] <= angles) & (angles < bins[i+1])] 
     if data_i.size > 0: 
      dist_order = np.argsort(cdist(data_i[:, :2], gdata[j, ::][np.newaxis]), axis=0) 
      if dist_order.size < npoint_per_octant+1: 
       [octantsort.append(data_i[dist_order[:npoint_per_octant][j]]) for j in range(dist_order.size)] 
      else: 
       [octantsort.append(data_i[dist_order[:npoint_per_octant][j]]) for j in range(npoint_per_octant)] 
      final = np.vstack(octantsort) 

    idata = [np.column_stack(data[k]) for k in range(len(data)) if data[k] not in final] 
    idata = np.vstack(idata) 

は、コードの最後の2行で、パフォーマンスを向上させるかこれを行うための効率的かつ神託方法はありますか?

+1

例/シミュレートされたデータ、典型的な/最大データセットのサイズは '最終作ってみる、より良いパフォーマンスを得るためとして、ファイルの読み取りコード – f5r5e5d

+0

を示す以上に役立つだろう'' set'。セットはO(1)時間で検索できます。 – rlbond

答えて

0

私が正しくあなたのコードを理解していれば、その後、私は、次の潜在的な節約を参照してください。

    • DEDENT final = ...ラインはそれは高価だarctanを使用しないでください。あなただけのオクタントは、すなわちデータではなく、データポイントにインデックスを格納し、「octantargsort」あなたoctantsortを作る代わりにargpartition
    • を使用し、フルargsortをしないゼロにし、
    • 相互に座標を比較したいので、自分自身;最後の1行で検索を保存し、削除のためにnp.deleteを使用できるようにします
    • リストの中にappendを使用しないでください。これによりすぐに破棄されるNoneのリストが生成されます。 を理解の範囲外に使用することもできます。
    • さらに、これらのリスト内包語はdata_i[dist_order[:npoint_per_octant]]をリストに変換する複雑な方法のように見えます。最後にvstackにしたいので、単にキャストしないでください。ここで

    これらのアイデアを示すいくつかのサンプルコードです:

    import numpy as np 
    
    def discard_nearest_in_each_octant(eater, eaten, n_eaten_p_eater): 
        # build octants 
        # start with quadrants ... 
        top, left = (eaten < eater).T 
        quadrants = [np.where(v&h)[0] for v in (top, ~top) for h in (left, ~left)] 
        dcoord2 = (eaten - eater)**2 
        dc2quadrant = [dcoord2[q] for q in quadrants] 
        # ... and split them 
        oct4158 = [q[:, 0] < q [:, 1] for q in dc2quadrant] 
        # main loop 
        dc2octants = [[q[o], q[~o]] for q, o in zip (dc2quadrant, oct4158)] 
        reloap = [[ 
         np.argpartition(o.sum(-1), n_eaten_p_eater)[:n_eaten_p_eater] 
         if o.shape[0] > n_eaten_p_eater else None 
         for o in opair] for opair in dc2octants] 
        # translate indices 
        octantargpartition = [q[so] if oap is None else q[np.where(so)[0][oap]] 
              for q, o, oaps in zip(quadrants, oct4158, reloap) 
              for so, oap in zip([o, ~o], oaps)] 
        octantargpartition = np.concatenate(octantargpartition) 
        return np.delete(eaten, octantargpartition, axis=0) 
    
  • 関連する問題