পাইথনের সাথে অ্যাট্রিবিউট টেবিলগুলি সংশোধন করার দ্রুততম পদ্ধতিগুলি?


12

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

def make_attribute_dict(fc, key_field, attr_list=['*']):
    dict = {}
    fc_field_objects = arcpy.ListFields(fc)
    fc_fields = [field.name for field in fc_field_objects if field.type != 'Geometry']
    if attr_list == ['*']:
        valid_fields = fc_fields
    else:
        valid_fields = [field for field in attr_list if field in fc_fields]
    if key_field not in valid_fields:
        cursor_fields = valid_fields + [key_field]
    else:
        cursor_fields = valid_fields
    with arcpy.da.SearchCursor(fc, cursor_fields) as cursor:
        for row in cursor:
            key = row[cursor_fields.index(key_field)]
            subdict = {}
            for field in valid_fields:
                subdict[field] = row[cursor_fields.index(field)]
            dict[key] = subdict
            del subdict
    return dict

এটি তুলনামূলকভাবে ছোট ডেটাসেটের জন্য দুর্দান্ত কাজ করে, তবে আমি কেবল এটি প্রায় 750,000 সারি এবং 15 টি ক্ষেত্রযুক্ত একটি টেবিলের উপর চালিয়েছি - একটি ফাইল জিওডাটাবেজে প্রায় 100 এমবি। এর উপর, ফাংশনটি আমার প্রত্যাশার চেয়ে অনেক ধীর গতিতে চলে: প্রায় 5-6 মিনিট (এবং এটি in_memoryকর্মক্ষেত্রে টেবিলটি অনুলিপি করার পরে )। আমি অভিধানে রূপান্তরটির গতি বাড়ানোর কোনও উপায় খুঁজে পেতে চাইছি বা পাইথন ব্যবহার করে বৃহত পরিমাণে অ্যাট্রিবিউট ডেটা ম্যানিপুলেট করার জন্য আরও ভাল কৌশল সম্পর্কে কিছুটা অন্তর্দৃষ্টি পেতে চাই।

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


2
আপনি আপনার স্ক্রিপ্টটিকে কতটা অনুকূল করতে পারেন তার সীমাবদ্ধ ফ্যাক্টরটি আপনার কার্সারের মাধ্যমে পুনরাবৃত্তি হতে সময় নিতে পারে। আপনি আপনার অভিধানগুলি তৈরি না করে কার্সারের মাধ্যমে পুনরাবৃত্তি হতে সময়কে কী তুলনা করেছেন?
জেসন

2
থেকে লাইন আউট মন্তব্য @Jason subdict = {}মাধ্যমে del subdictপ্রায় 10 সেকেন্ডের একটি প্রক্রিয়াকরণের উৎপাদ।
nmpeterson

আপনি সম্ভবত আমাকে এই সম্পর্কে আরো জানতে, কিন্তু শুধুমাত্র অন্যান্য জিনিস আমি অপ্টিমাইজেশান পরিপ্রেক্ষিতে প্রস্তাব করত কিনা কলিং এ খুঁজছেন হয় subdict[field] = row[cursor_fields.index(field)]কলিং চেয়ে দ্রুত subdict[field] = row.getValue(field)। পরের দৃশ্যে আপনি এক ধাপ সম্পাদন করবেন ... যদিও দুটি তালিকাকে তালিকাভুক্ত করা ( cursor_fieldsএবং row) এবং একক ইএসআরআই প্রক্রিয়া ব্যবহারের মধ্যে পারফরম্যান্সের পার্থক্য খুব ভাল নাও হতে পারে এবং আরও খারাপ হতে পারে!
জেসন

উত্তর:


16

আমি মনে করি সমস্যাটি সম্ভবত আপনার দুটি লাইন যেখানে আপনি ক্ষেত্রগুলিতে চলে যাচ্ছেন এবং প্রতিটি অভিধানকে আপনার subdictঅভিধানে পৃথকভাবে যুক্ত করছেন ।

for field in valid_fields:
    subdict[field] = row[cursor_fields.index(field)]

আপনার rowঅবজেক্টটি আপনার ক্ষেত্রের মতো একই ক্রমে ইতিমধ্যে একটি টুপল, সেটির সুবিধা নিন এবং zipফাংশনটি ব্যবহার করুন ।

def make_attribute_dict(fc, key_field, attr_list=['*']):
    attdict = {}
    fc_field_objects = arcpy.ListFields(fc)
    fc_fields = [field.name for field in fc_field_objects if field.type != 'Geometry']
    if attr_list == ['*']:
        valid_fields = fc_fields
    else:
        valid_fields = [field for field in attr_list if field in fc_fields]
    #Ensure that key_field is always the first field in the field list
    cursor_fields = [key_field] + list(set(valid_fields) - set([key_field]))
    with arcpy.da.SearchCursor(fc, cursor_fields) as cursor:
        for row in cursor:
            attdict[row[0]] = dict(zip(cursor.fields,row))
    return attdict

এটি আমার সিস্টেমে 8 সেকেন্ডের মধ্যে 218k রেকর্ড 16 ফিল্ড ফাইল জিওডাটাবেস বৈশিষ্ট্য শ্রেণীর মাধ্যমে স্থান পেয়েছে।

সম্পাদনা: আরও কঠোর পরীক্ষার চেষ্টা করা হয়েছে। ওবিজেইসিটিড এবং শেপ সহ 16 টি ক্ষেত্রের সাথে একটি দূরবর্তী এসডিই সংযোগের উপরে 518k রেকর্ডগুলি 32-বিটে চালিত হয়। 11 সেকেন্ড :)


1
নোট করুন যে আমি key_fieldপ্রথম ক্ষেত্রটি তৈরি করেছিলাম যাতে আমি row[0]এর মান উল্লেখ করতে ব্যবহারের উপর নির্ভর করতে পারি key_field। আমাকে আপনার ভেরিয়েবলটিও পরিবর্তন dictকরতে হয়েছিল attdict। ডিক একটি কীওয়ার্ড, এবং সেই কীওয়ার্ড ছাড়া আমি ব্যবহার করতে পারি নাdict(zip())
blord-castillo

6
চালাক। এটি হ'ল একধরণের মিষ্টি ইডিয়োমেটিক পাইথন যা arcpy.daসক্ষম করতে বোঝানো হয়েছে।
জেসন শিয়েরার

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