দক্ষতার সাথে 200k বহুভুজগুলির 1 ম অর্ডার প্রতিবেশী সন্ধান করুন


14

208,781 জনগণনা ব্লক গোষ্ঠীর প্রত্যেকের জন্য, আমি এর 1 ম অর্ডার প্রতিবেশীদের সমস্ত আইএফসি আইডি পুনরুদ্ধার করতে চাই। আমি সমস্ত টিআইজিআর বাউন্ডারি ডাউনলোড করেছি এবং একক 1 জিবি শেফফাইলে একত্রিত করেছি।

আমি একটি অর্ক পাইথন স্ক্রিপ্ট চেষ্টা করেছি যা এর মূল অংশে BOUNDARY_TOUCHES এর জন্য সিলেক্ট লেয়ারবায়লোকেশন ব্যবহার করে, তবে প্রতিটি ব্লক গোষ্ঠীর জন্য এটি আমার চেয়ে কম ধীরে ধীরে 1 সেকেন্ডের বেশি সময় নেয়। এটি একই স্থানে থাকা গ্রুপগুলিতে ব্লক বাছাই করার জন্য আমি সিলেক্টায়ারবাইএল লোকেশন অনুসন্ধান সীমাবদ্ধ করার পরেও is আমি এই স্ক্রিপ্টটি পেয়েছি , তবে এটি অভ্যন্তরীণভাবে সিলেক্টায়ারবাইলোকেশনও ব্যবহার করে যাতে এটি কোনও দ্রুত হয় না।

সমাধানটি আর্ক-ভিত্তিক হতে হবে না - আমি অন্যান্য প্যাকেজগুলির জন্য উন্মুক্ত, যদিও আমি পাইথনের সাথে কোডিং করা সবচেয়ে স্বাচ্ছন্দ্যযুক্ত।


2
সংস্করণ 9.3 সাল থেকে, স্থানিক পরিসংখ্যান সরঞ্জাম বাক্সে এটি করার জন্য সরঞ্জাম রয়েছে। 10.0 থেকে শুরু করে, তারা খুব দক্ষ। আমি তুলনীয় আকারের (একটি ব্লকের সমস্ত ব্লক ) আকারের ফাইলে একই ধরণের অপারেশন চালানোর কথা স্মরণ করি এবং এটি 30 মিনিটের মধ্যে সম্পন্ন হয়, এর মধ্যে 15 টি কেবল ডিস্ক আই / ও এর জন্য - এবং এটি দুটি বছর আগে বেশ ধীর মেশিনে হয়েছিল। পাইথন উত্স কোডটিও অ্যাক্সেসযোগ্য।
whuber

স্থানিক পরিসংখ্যানগুলির কোন জিওপ্রসেসিংয়ের সরঞ্জাম আপনি ব্যবহার করেছেন?
dmahr

1
আমি এর নাম ভুলে যাই; এটি বিশেষত বহুভুজ প্রতিবেশী সম্পর্কের একটি সারণী তৈরির জন্য। সহায়তা সিস্টেম আপনাকে প্রতিবেশী-ভিত্তিক স্থানিক পরিসংখ্যান সরঞ্জামগুলির কোনও চালনার আগে এই টেবিলটি তৈরি করতে উত্সাহ দেয় , যাতে সরঞ্জামগুলি প্রতিবার চালানোর সময় ফ্লাইতে এই তথ্যটি পুনরায় সংশোধন করতে না হয়। কমপক্ষে 9.x সংস্করণে একটি উল্লেখযোগ্য সীমাবদ্ধতা হ'ল আউটপুটটি .dbf ফর্ম্যাটে ছিল। একটি বড় ইনপুট শেফফিলের জন্য যা কাজ করবে না, এক্ষেত্রে আপনাকে হয় অপারেশনটি টুকরো টুকরো করে ফেলতে হবে বা পাইথন কোডটি হ্যাক করতে হবে আরও ভাল ফর্ম্যাটে আউটপুট করতে।
whuber


হ্যাঁ, এটা। পাইথন কোডটি পুরোপুরি অভ্যন্তরীণ আর্কজিআইএস ক্ষমতাগুলি ব্যবহার করে (যা স্থানিক সূচকগুলি ব্যবহার করে), অ্যালগোরিদমকে বেশ দ্রুত তৈরি করে।
whuber

উত্তর:


3

আপনার যদি ডেস্কটপের জন্য বা যদি সম্ভবত এর আগে আরকিজিআইএস 10.2 এ অ্যাক্সেস থাকে তবে আমি মনে করি বহুভুজ প্রতিবেশী (বিশ্লেষণ) সরঞ্জাম যা:

বহুভুজ সংযোগের ভিত্তিতে পরিসংখ্যানগুলির সাথে একটি সারণী তৈরি করে (ওভারল্যাপ, কাকতালীয় প্রান্ত বা নোড)।

বহুভুজ প্রতিবেশী

এই কাজটি এখন আরও সহজ করে তুলতে পারে।


ধন্যবাদ, পলিজিও আমি স্বীকৃত উত্তরটি আপডেট করেছি যাতে বহুভুজ প্রতিবেশী সরঞ্জামটি আরও কিছুটা এক্সপোজার পায়। এটি অবশ্যই আমার ম্যানুয়াল পাইথন-ভিত্তিক পদ্ধতির চেয়ে আরও শক্তিশালী, যদিও আমি নিশ্চিত না যে বড় ডেটাসেটের সাথে স্কেলিবিলিটি কীভাবে তুলনা করে।
dmahr

আমি বর্তমানে 10.3 ব্যবহার করছি এবং এটি আমার শেপফাইলে 300 ডলার সেন্সাস ব্লক সহ ব্যর্থ হয়।
soandos

@ সানডোস মনে হচ্ছে এটি একটি নতুন প্রশ্ন হিসাবে গবেষণা / জিজ্ঞাসা করার উপযুক্ত হতে পারে।
পলিজিও

8

আরকজিআইএস এড়ানোর সমাধানের জন্য পাইসাল ব্যবহার করুন । আপনি আকার ব্যবহার করে সরাসরি ওজন পেতে পারেন:

w = pysal.rook_from_shapefile("../pysal/examples/columbus.shp")

অথবা

w = pysal.queen_from_shapefile("../pysal/examples/columbus.shp")

জন্য আগাইয়া ডক্স আরও তথ্যের জন্য।


3

শুধু একটি আপডেট। হুবার পরামর্শ অনুসরণ করার পরে, আমি আবিষ্কার করেছি যে জেনারেট স্পেশিয়াল ওয়েট ম্যাট্রিক্স প্রতিবেশী নির্ধারণের জন্য পাইথনের লুপ এবং অভিধানগুলি কেবল ব্যবহার করে। আমি নীচে প্রক্রিয়া পুনরুত্পাদন।

প্রথম অংশটি প্রতিটি ব্লক গ্রুপের প্রতিটি শীর্ষবিন্দুতে লুপ করে। এটি কী হিসাবে মেরুদণ্ডের স্থানাঙ্কের সাথে একটি অভিধান এবং ব্লক গ্রুপ আইডির একটি তালিকা তৈরি করে যা মান হিসাবে স্থানাঙ্কের একটি সূচক রয়েছে। মনে রাখবেন যে এর জন্য শীর্ষস্থানীয় ঝরঝরে ডেটাসেট প্রয়োজন, কারণ নিখুঁত ভার্টেক্স / ভার্টেক্স ওভারল্যাপ প্রতিবেশীর সম্পর্ক হিসাবে নিবন্ধিত হবে। ভাগ্যক্রমে আদমশুমারি ব্যুরোর টিআইজিআর ব্লক গ্রুপের আকারগুলি সঠিকভাবে এ ক্ষেত্রে সঠিক।

দ্বিতীয় অংশটি প্রতিটি ব্লক গ্রুপের প্রতিটি ভার্টেক্সের মধ্য দিয়ে ফিরে আসে। এটি কী হিসাবে ব্লক গ্রুপ আইডি এবং একটি ব্লক গ্রুপের প্রতিবেশী আইডিগুলিকে মান হিসাবে একটি অভিধান তৈরি করে।

# Create dictionary of vertex coordinate : [...,IDs,...]
BlockGroupVertexDictionary = {}
BlockGroupCursor = arcpy.SearchCursor(BlockGroups.shp)
BlockGroupDescription = arcpy.Describe(BlockGroups.shp)
BlockGroupShapeFieldName = BlockGroupsDescription.ShapeFieldName
#For every block group...
for BlockGroupItem in BlockGroupCursor :
    BlockGroupID = BlockGroupItem.getValue("BKGPIDFP00")
    BlockGroupFeature = BlockGroupItem.getValue(BlockGroupShapeFieldName)
    for BlockGroupPart in BlockGroupFeature:
        #For every vertex...
        for BlockGroupPoint in BlockGroupPart:
            #If it exists (and isnt empty interior hole signifier)...
            if BlockGroupPoint:
                #Create string version of coordinate
                PointText = str(BlockGroupPoint.X)+str(BlockGroupPoint.Y)
                #If coordinate is already in dictionary, append this BG's ID
                if PointText in BlockGroupVertexDictionary:
                    BlockGroupVertexDictionary[PointText].append(BlockGroupID)
                #If coordinate is not already in dictionary, create new list with this BG's ID
                else:
                    BlockGroupVertexDictionary[PointText] = [BlockGroupID]
del BlockGroupItem
del BlockGroupCursor


#Create dictionary of ID : [...,neighbors,...]
BlockGroupNeighborDictionary = {}
BlockGroupCursor = arcpy.SearchCursor(BlockGroups.shp)
BlockGroupDescription = arcpy.Describe(BlockGroups.shp)
BlockGroupShapeFieldName = BlockGroupDescription.ShapeFieldName
#For every block group
for BlockGroupItem in BlockGroupCursor:
    ListOfBlockGroupNeighbors = []
    BlockGroupID = BlockGroupItem.getValue("BKGPIDFP00")
    BlockGroupFeature = BlockGroupItem.getValue(BlockGroupShapeFieldName)
    for BlockGroupPart in BlockGroupFeature:
        #For every vertex
        for BlockGroupPoint in BlockGroupPart:
            #If it exists (and isnt interior hole signifier)...
            if BlockGroupPoint:
                #Create string version of coordinate
                PointText = str(BlockGroupPoint.X)+str(BlockGroupPoint.Y)
                if PointText in BlockGroupVertexDictionary:
                    #Get list of block groups that have this point as a vertex
                    NeighborIDList = BlockGroupVertexDictionary[PointText]
                    for NeighborID in NeighborIDList:
                        #Don't add if this BG already in list of neighbors
                        if NeighborID in ListOfBGNeighbors:
                            pass
                        #Add to list of neighbors (as long as its not itself)
                        elif NeighborID != BlockGroupID:
                            ListOfBGNeighbors.append(NeighborID)
    #Store list of neighbors in blockgroup object in dictionary
    BlockGroupNeighborDictionary[BlockGroupID] = ListOfBGNeighbors

del BlockGroupItem
del BlockGroupCursor
del BlockGroupVertexDictionary

অন্ধকারে আমি বুঝতে পারি যে আমি দ্বিতীয় অংশের জন্য আবার একটি আলাদা পদ্ধতি ব্যবহার করতে পারি যার জন্য আবার শেফফিলের মধ্য দিয়ে লুপিংয়ের প্রয়োজন হয় না। তবে এটি আমি ব্যবহার করেছি এবং এটি একসাথে ব্লকের বিভিন্ন গোষ্ঠীর পক্ষেও বেশ ভাল কাজ করে। আমি এটি পুরো মার্কিন যুক্তরাষ্ট্রে করার চেষ্টা করিনি, তবে এটি পুরো রাজ্যের জন্য কার্যকর করতে পারে।


2

PostgreSQL এবং PostGIS ব্যবহার করার বিকল্প হতে পারে । এই সাইটে অনুরূপ গণনা সম্পাদন করার জন্য আমি কয়েকটি প্রশ্ন জিজ্ঞাসা করেছি:

সফ্টওয়্যারটির বিভিন্ন টুকরা একসাথে কীভাবে খাপ খায় তা নির্ধারণ করার জন্য আমি খাড়া শেখার বক্ররেখা পেয়েছি, তবে বড় ভেক্টরের স্তরগুলিতে গণনা করার জন্য আমি এটি দুর্দান্ত পেয়েছি। আমি কয়েক মিলিয়ন বহুভুজের নিকটস্থ কিছু নিকটবর্তী প্রতিবেশী গণনা চালিয়েছি এবং এটি আর্কজিআইএস এর সাথে তুলনায় দ্রুত হয়েছে।


1

কিছু মন্তব্য ... এসরি / আর্কজিআইএস পদ্ধতি বর্তমানে তথ্য ধরে রাখতে অভিধান ব্যবহার করে তবে মূল গণনাগুলি সি ++ তে বহুভুজ প্রতিবেশী সরঞ্জামটি ব্যবহার করে করা হয়। এই সরঞ্জামটি একটি সারণী উত্পন্ন করে যা সামঞ্জস্যের তথ্যের পাশাপাশি অংশীদারি সীমানার দৈর্ঘ্যের মতো alচ্ছিক অ্যাটর্স ধারণ করে। আপনি যদি জেনারেট স্পিটিয়াল ওয়েট ম্যাট্রিক্স সরঞ্জামটি ব্যবহার করতে পারেন তবে আপনি যদি তথ্যটি বারবার ব্যবহার করতে চান এবং পরবর্তীতে পুনরায় ব্যবহার করতে চান। ডিকশনারি [এলোমেলো অ্যাক্সেস] ডাব্লু / সামঞ্জস্যের তথ্য উত্পন্ন করতে আপনি ওয়েটস ইউটিলিটিসে এই ফাংশনটি ব্যবহার করতে পারেন:

contDict = polygonNeighborDict(inputFC, masterField, contiguityType = "ROOK")

যেখানে ইনপুটএফসি = যে কোনও ধরণের বহুভুজ বৈশিষ্ট্য শ্রেণি রয়েছে, মাস্টারফিল্ডটি unique "রুক", "কোয়েইন" in এর পূর্ণসংখ্যার এবং স্বচ্ছলতার টাইপের "অনন্য আইডি" ক্ষেত্র}

পাইথন ব্যবহারকারীদের জন্য ট্যাবুলার দিকটি এড়িয়ে সরাসরি একটি পুনরুক্তিতে যাওয়ার জন্য এসরিতে প্রচেষ্টা রয়েছে যা অনেকগুলি ব্যবহারের ক্ষেত্রে দ্রুততর হবে। আর পি-এসএল এবং এসপিডিপ প্যাকেজ হ'ল দুর্দান্ত বিকল্প [ রাদেকের উত্তর দেখুন] । আমি মনে করি আপনাকে এই প্যাকেজগুলিতে ডেটা ফর্ম্যাট হিসাবে শেফফিলগুলি ব্যবহার করতে হবে যা ডাব্লু / এই থ্রেড ইনপুট ফর্ম্যাটে রয়েছে। বহুভুজগুলির মধ্যে ওভারল্যাপিং বহুভুজগুলির পাশাপাশি বহুভুজগুলির সাথে কীভাবে তারা কাজ করে তা নিশ্চিত নয় Not এসডাব্লুএম তৈরি করার পাশাপাশি আমি বর্ণিত ফাংশনটি সেই স্থানিক সম্পর্কগুলিকে "রুক" এবং "কুইন" প্রতিবেশী হিসাবে গণ্য করবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.