मैं लिडार के 3 डी पॉइंटक्लाउड के साथ काम कर रहा हूं। अंक इस प्रकार दिखाई देने वाले संख्यात्मक सरणी द्वारा दिए गए हैं:
points = np.array([[61651921, 416326074, 39805], [61605255, 416360555, 41124], [61664810, 416313743, 39900], [61664837, 416313749, 39910], [61674456, 416316663, 39503], [61651933, 416326074, 39802], [61679969, 416318049, 39500], [61674494, 416316677, 39508], [61651908, 416326079, 39800], [61651908, 416326087, 39802], [61664845, 416313738, 39913], [61674480, 416316668, 39503], [61679996, 416318047, 39510], [61605290, 416360572, 41118], [61605270, 416360565, 41122], [61683939, 416313004, 41052], [61683936, 416313033, 41060], [61679976, 416318044, 39509], [61605279, 416360555, 41109], [61664837, 416313739, 39915], [61674487, 416316666, 39505], [61679961, 416318035, 39503], [61683943, 416313004, 41054], [61683930, 416313042, 41059]])
मैं अपने डेटा आकार के घनों में बांटा रखना चाहते हैं 50*50*50
ताकि हर घन कुछ hashable सूचकांक और मेरे की numpy सूचकांक को बरकरार रखता है points
इसमें । विभाजन प्राप्त करने के लिए, मैं यह निर्धारित cubes = points \\ 50
करता हूं :
cubes = np.array([[1233038, 8326521, 796], [1232105, 8327211, 822], [1233296, 8326274, 798], [1233296, 8326274, 798], [1233489, 8326333, 790], [1233038, 8326521, 796], [1233599, 8326360, 790], [1233489, 8326333, 790], [1233038, 8326521, 796], [1233038, 8326521, 796], [1233296, 8326274, 798], [1233489, 8326333, 790], [1233599, 8326360, 790], [1232105, 8327211, 822], [1232105, 8327211, 822], [1233678, 8326260, 821], [1233678, 8326260, 821], [1233599, 8326360, 790], [1232105, 8327211, 822], [1233296, 8326274, 798], [1233489, 8326333, 790], [1233599, 8326360, 790], [1233678, 8326260, 821], [1233678, 8326260, 821]])
मेरा वांछित आउटपुट इस तरह दिखता है:
{(1232105, 8327211, 822): [1, 13, 14, 18]),
(1233038, 8326521, 796): [0, 5, 8, 9],
(1233296, 8326274, 798): [2, 3, 10, 19],
(1233489, 8326333, 790): [4, 7, 11, 20],
(1233599, 8326360, 790): [6, 12, 17, 21],
(1233678, 8326260, 821): [15, 16, 22, 23]}
मेरे वास्तविक पॉइंटक्लाउड में लाखों-करोड़ों 3D अंक हैं। इस तरह की ग्रुपिंग करने का सबसे तेज़ तरीका क्या है?
मैंने कई तरह के समाधानों की कोशिश की है। यहाँ समय गणना की तुलना यह मानते हुए कि अंकों का आकार 20 मिलियन है और अलग-अलग क्यूब्स का आकार 1 मिलियन है।
पंडस [टपल (एलएम) -> np.array (dtype = int64)]
import pandas as pd
print(pd.DataFrame(cubes).groupby([0,1,2]).indices)
#takes 9sec
डिफ़ाल्डडिक्ट [elem.tobytes () या tuple -> सूची]
#thanks @abc:
result = defaultdict(list)
for idx, elem in enumerate(cubes):
result[elem.tobytes()].append(idx) # takes 20.5sec
# result[elem[0], elem[1], elem[2]].append(idx) #takes 27sec
# result[tuple(elem)].append(idx) # takes 50sec
numpy_indexed [int -> np.array]
# thanks @Eelco Hoogendoorn for his library
values = npi.group_by(cubes).split(np.arange(len(cubes)))
result = dict(enumerate(values))
# takes 9.8sec
पंडों + आयामीता में कमी [int -> np.array (dtype = int64)]
# thanks @Divakar for showing numexpr library:
import numexpr as ne
def dimensionality_reduction(cubes):
#cubes = cubes - np.min(cubes, axis=0) #in case some coords are negative
cubes = cubes.astype(np.int64)
s0, s1 = cubes[:,0].max()+1, cubes[:,1].max()+1
d = {'s0':s0,'s1':s1,'c0':cubes[:,0],'c1':cubes[:,1],'c2':cubes[:,2]}
c1D = ne.evaluate('c0+c1*s0+c2*s0*s1',d)
return c1D
cubes = dimensionality_reduction(cubes)
result = pd.DataFrame(cubes).groupby([0]).indices
# takes 2.5 seconds
यहांcubes.npz
फ़ाइल डाउनलोड करना और कमांड का उपयोग करना संभव है
cubes = np.load('cubes.npz')['array']
प्रदर्शन समय की जांच करने के लिए।
numpy_indexed
केवल इसे भी अप्रोच करता है। मुझे लगता है कि यह सही है। मैं pandas
वर्तमान में अपनी वर्गीकरण प्रक्रियाओं के लिए उपयोग करता हूं।