একটি বৃহত ফাইল কীভাবে পড়তে হয় - লাইন লাইন করে?


536

আমি একটি সম্পূর্ণ ফাইলের প্রতিটি লাইন পুনরাবৃত্তি করতে চান। এটি করার একটি উপায় হ'ল পুরো ফাইলটি পড়া, এটি একটি তালিকায় সংরক্ষণ করা, তারপরে আগ্রহের লাইনে চলে যাওয়া। এই পদ্ধতিতে প্রচুর স্মৃতি ব্যবহৃত হয়, তাই আমি একটি বিকল্প খুঁজছি।

আমার কোড এখন পর্যন্ত:

for each_line in fileinput.input(input_file):
    do_something(each_line)

    for each_line_again in fileinput.input(input_file):
        do_something(each_line_again)

এই কোড নির্বাহ একটি ত্রুটির বার্তা দেয়: device active

কোন পরামর্শ?

উদ্দেশ্যটি হ'ল জোড়-ভিত্তিক স্ট্রিং মিলকে গণনা করা, যার অর্থ ফাইলের প্রতিটি লাইন, আমি প্রতিটি অন্যান্য লাইনের সাথে লেভেনস্টাইন দূরত্ব গণনা করতে চাই।


4
প্রতিটি লাইনের জন্য আপনাকে কেন আবার পুরো ফাইলটি পড়তে হবে? আপনি যদি কেউ কাউকে কী করার জন্য চেষ্টা করছেন তা যদি আপনি বলেন তবে সম্ভবত এটি আরও ভাল পদ্ধতির পরামর্শ দিতে পারে।
জেজেজে

উত্তর:


1269

ফাইল পড়ার সঠিক, সম্পূর্ণ পাইথোনিক উপায়টি হল:

with open(...) as f:
    for line in f:
        # Do something with 'line'

withবিবৃতি হ্যান্ডলগুলি খোলার এবং ফাইল বন্ধ সহ একটি ব্যতিক্রম ভেতরের ব্লক উত্থাপিত হলে। for line in fএকইরূপে ফাইল বস্তুর fএকটি iterable, যা স্বয়ংক্রিয়ভাবে বাফার ব্যবহার ইনপুট / আউটপুট এবং মেমরি ব্যবস্থাপনা যাতে আপনি বড় ফাইল সম্পর্কে চিন্তা করতে হবে না হিসাবে।

এটির জন্য সুস্পষ্ট উপায় - এবং কেবলমাত্র একটিই - সেখানে থাকতে হবে।


14
হ্যাঁ, এটি পাইথন ২.6 এবং
তারপরের

3
ডেটা পাইপলাইনগুলির সাথে লেনদেন করার জন্য আমি ব্যক্তিগতভাবে জেনারেটর এবং করোটিনগুলিকে পছন্দ করি।
jldupont

4
কোন ফাইলটি যদি একটি বিশাল টেক্সট ফাইল হয় তবে এক লাইনের সাথে এবং শব্দটি প্রক্রিয়া করার জন্য ধারণাটি কী হবে?
এমফকাব্রের

4
কেউ কীভাবে for line in f:কাজ করছে তা ব্যাখ্যা করতে পারে ? আমি বলতে চাইছি কীভাবে ফাইল অবজেক্টের উপর পুনরাবৃত্তি সম্ভব?
হ্যাক

11
যদি আপনি কোনও বস্তুর উপরে পুনরাবৃত্তি করেন তবে পাইথন বস্তুর একটি বিশেষ নামক পদ্ধতির তালিকায় সন্ধান করে __iter__যা এটি করতে হবে। ফাইল অবজেক্টস রেখাগুলির উপরে একটি পুনরাবৃত্তিকে ফেরত দিতে এই বিশেষ পদ্ধতিটি সংজ্ঞায়িত করে। (মোটামুটি।)
ক্যাট্রিয়েল

130

ক্রমযুক্ত ক্রমে দুটি মেমরি দক্ষ উপায় (প্রথমটি সেরা) -

  1. ব্যবহারের with- পাইথন 2.5 থেকে উপরে সমর্থিত
  2. yieldআপনি কী পরিমাণে পড়তে চান তা নিয়ন্ত্রণ করতে চাইলে ব্যবহার করুন

1. ব্যবহার with

withবড় ফাইলগুলি পড়ার দুর্দান্ত এবং দক্ষ অজগর উপায়। সুবিধা - 1) ফাইল অবজেক্ট withএক্সিকিউশন ব্লক থেকে প্রস্থান করার পরে স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যায় । 2) withব্লকের ভিতরে ব্যতিক্রম হ্যান্ডলিং । 3) মেমরি forলুপটি fলাইন দ্বারা ফাইল অবজেক্টের মধ্য দিয়ে পুনরাবৃত্তি করে। অভ্যন্তরীণভাবে এটি আইও বাফার করে (ব্যয়বহুল আইও অপারেশনে অনুকূলিতকরণ) এবং মেমরি পরিচালনা করে।

with open("x.txt") as f:
    for line in f:
        do something with data

2. এর ব্যবহার yield

কখনও কখনও কেউ প্রতিটি পুনরাবৃত্তিতে কতটা পড়তে হবে তার জন্য আরও সূক্ষ্ম নিয়ন্ত্রণ পেতে চাইবে want সেক্ষেত্রে ইটারফলন ব্যবহার করুন । এই পদ্ধতির সাহায্যে নোটটির স্পষ্টতই শেষে ফাইলটি বন্ধ করা দরকার।

def readInChunks(fileObj, chunkSize=2048):
    """
    Lazy function to read a file piece by piece.
    Default chunk size: 2kB.
    """
    while True:
        data = fileObj.read(chunkSize)
        if not data:
            break
        yield data

f = open('bigFile')
for chuck in readInChunks(f):
    do_something(chunk)
f.close()

বিপদ এবং সম্পূর্ণতার জন্য - নীচের পদ্ধতিগুলি বড় ফাইলগুলি পড়ার জন্য মার্জিত হিসাবে ভাল নয় তবে গোলাকার বোঝার জন্য দয়া করে পড়ুন।

পাইথনে, কোনও ফাইল থেকে লাইন পড়ার সর্বাধিক সাধারণ উপায় হল নিম্নলিখিতটি করা:

for line in open('myfile','r').readlines():
    do_something(line)

এটি সম্পন্ন করার পরে, readlines()ফাংশন ( read()ফাংশনের জন্য একই প্রযোজ্য ) পুরো ফাইলটিকে মেমরিতে লোড করে, তারপরে এটি পুনরাবৃত্তি করে। বড় ফাইলগুলির জন্য কিছুটা উন্নত পদ্ধতির (প্রথম উল্লিখিত দুটি পদ্ধতি সবচেয়ে ভাল) fileinputমডিউলটি ব্যবহার করা নিম্নরূপ:

import fileinput

for line in fileinput.input(['myfile']):
    do_something(line)

fileinput.input()কল ক্রমানুসারে লাইন লেখা, কিন্তু তাদের স্মৃতিতে রাখা না পরে তারা পড়তে করে থাকেন বা এমনকি কেবল তাই এই, যেহেতু fileএ পাইথন iterable হয়।

তথ্যসূত্র

  1. বিবৃতি সহ পাইথন

9
-1 এটি মূলত কখনই করা ভাল ধারণা নয় for line in open(...).readlines(): <do stuff>। েরগেরগ?! আপনি কোনও লাভের জন্য পাইথনের চতুর বাফার আইট্রেটর আইও এর সমস্ত সুবিধা হারিয়ে ফেলেছেন।
ক্যাটরিল

5
@ শ্রিকার: একটি সমস্যার সম্ভাব্য সকল সমাধান দেওয়ার জন্য একটি সময় এবং জায়গা রয়েছে; একটি শিক্ষানবিশকে ফাইল ইনপুট কীভাবে করবেন তা শেখানো নয়। ভুল উত্তর দিয়ে পূর্ণ দীর্ঘ পোস্টের নীচে সঠিক উত্তরটি সমাহিত করা ভাল শিক্ষাদান করে না।
ক্যাটরিল

6
@ শ্রিকার: আপনি সঠিক পোস্টটিকে শীর্ষে রেখে আপনার পোস্টটি উল্লেখযোগ্যভাবে আরও ভাল করে তুলতে পারেন, তারপরে এটি উল্লেখ করা readlinesএবং ব্যাখ্যা করা কেন এটি করা ভাল জিনিস নয় (কারণ এটি ফাইলটি মেমরির মধ্যে পড়ে) এবং ব্যাখ্যা করে fileinputমডিউলটি কী করে এবং আপনি কেন অন্যান্য পদ্ধতিতে এটি ব্যবহার করতে চাইতে পারে, তারপরে ফাইলটিকে ছাঁকানো কীভাবে আইওকে আরও উন্নত করে এবং চুনকিংয়ের ফাংশনটির উদাহরণ দেয় (তবে উল্লেখ করা যে পাইথন এটি ইতিমধ্যে আপনার জন্য করে তাই আপনার দরকার নেই)। তবে একটি সহজ সমস্যা সমাধানের জন্য পাঁচটি উপায় প্রদান করা, যার মধ্যে চারটি ক্ষেত্রে এই ক্ষেত্রে ভুল, ভাল নয়।
ক্যাট্রিয়েল

2
সম্পূর্ণতার জন্য আপনি যা কিছু যোগ করুন না কেন, এটি সর্বশেষে যুক্ত করুন, প্রথমে নয়। প্রথমে সঠিক উপায়টি প্রদর্শন করুন।
m000

6
@ কেটরিলেক্স আমার উত্তরটি পুনরায় পর্যালোচনা করেছে এবং দেখতে পেয়েছে যে এটি পুনর্গঠনের পরোয়ানা রয়েছে। আমি দেখতে পাচ্ছি যে পূর্বের উত্তর কীভাবে বিভ্রান্তির কারণ হতে পারে। আশা করি এটি ভবিষ্যতের ব্যবহারকারীদের জন্য এটি পরিষ্কার করে দেবে।
শ্রীকর অপালরাজু

37

নতুন লাইনের স্ট্রিপ করতে:

with open(file_path, 'rU') as f:
    for line_terminated in f:
        line = line_terminated.rstrip('\n')
        ...

সঙ্গে সার্বজনীন সম্পর্কে newline সমর্থন সব টেক্সট ফাইল লাইনের বন্ধ করে দেওয়া হবে বলে মনে হবে '\n', যাই হোক না কেন ফাইলে terminators, '\r', '\n', অথবা '\r\n'

সম্পাদনা - সর্বজনীন নতুন লাইন সমর্থন নির্দিষ্ট করতে:

  • ইউনিক্সে পাইথন 2 - open(file_path, mode='rU')- প্রয়োজনীয় [ধন্যবাদ @ ডেভ ]
  • উইন্ডোজে পাইথন 2 open(file_path, mode='rU')- optionচ্ছিক
  • পাইথন 3 - al open(file_path, newline=None)চ্ছিক

newlineপ্যারামিটারটি কেবল পাইথন 3 এ সমর্থিত এবং এতে ডিফল্ট হয় Nonemodeথেকে প্যারামিটার অক্ষমতা 'r'সব ক্ষেত্রেই। UWindows এ পাইথন 3. পাইথন 2 অবচিত অন্য কিছু প্রক্রিয়া অনুবাদ প্রদর্শিত হবে হয় \r\nথেকে \n

দস্তাবেজ:

নেটিভ লাইন টার্মিনেটর সংরক্ষণ করতে:

with open(file_path, 'rb') as f:
    with line_native_terminated in f:
        ...

বাইনারি মোডটি এখনও লাইনগুলিতে ফাইলটি পার্স করতে পারে in। প্রতিটি লাইনে ফাইলটিতে যা কিছু টার্মিনেটর রয়েছে তা থাকবে।

ধন্যবাদ @katrielalex এর উত্তর , পাইথন এর খোলা () ডক, এবং iPython পরীক্ষায়।


1
পাইথন ২.7 এ আমাকে open(file_path, 'rU')সর্বজনীন নিউলাইনগুলি সক্ষম করতে হয়েছিল।
ডেভ

17

পাইথনে ফাইল পড়ার এটি একটি সম্ভাব্য উপায়:

f = open(input_file)
for line in f:
    do_stuff(line)
f.close()

এটি একটি সম্পূর্ণ তালিকা বরাদ্দ না। এটি রেখার উপরে পুনরাবৃত্তি করে।


2
এটি কাজ করার সময় এটি অবশ্যই প্রচলিত উপায় নয়। ক্যানোনিকাল উপায় হ'ল একটি প্রসঙ্গের মোড়ক ব্যবহার করা with open(input_file) as f:। এটি আপনাকে সংরক্ষণ করে f.close()এবং নিশ্চিত করে যে আপনি দুর্ঘটনাক্রমে এটি বন্ধ করতে ভুলবেন না। ফাইল পড়ার সময় মেমরির ফাঁস এবং সমস্তগুলি প্রতিরোধ করে।
মাস্ত্ত

1
যেমন @ মাস্ট বলেছেন, এটি ক্যানোনিকাল উপায় নয়, তাই এর জন্য ডাউনওয়েট করুন।
আজুাক্স

12

আমি কোথা থেকে আসছি সে সম্পর্কে সামনে কিছু প্রসঙ্গ। কোড স্নিপেটস শেষ হয়।

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

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

আমি সাধারণত প্রথমে gnu সরঞ্জামগুলি ব্যবহার করে ফাইলটি সারি অনুসারে ভাঙতে চাই এবং তারপরে পাইথন প্রোগ্রামে সমান্তরালে সেগুলি খুঁজে পেতে এবং পড়তে গ্লোব-ফাইলমাস্ক করে ফেলি। আমি সাধারণত 1000+ আংশিক ফাইলের মতো কিছু ব্যবহার করি। এই কৌশলগুলি করা প্রক্রিয়াকরণের গতি এবং মেমরির সীমাতে প্রচুর সহায়তা করে।

পান্ডাস ডেটা ফ্রেম.ড্রেড_সিএসভি একক থ্রেডযুক্ত যাতে আপনি সমান্তরাল সম্পাদনের জন্য একটি মানচিত্র () চালিয়ে পান্ডা তৈরি করতে দ্রুত এই কৌশলগুলি করতে পারেন। আপনি সরল পুরাতন অনুক্রমিক পান্ডাস ডেটা ফ্রেম.ড্রেড_সিএসভি দিয়ে দেখতে এইচটিপি ব্যবহার করতে পারেন, কেবল একটি কোরের 100% সিপিইউ হ'ল পিডি.ড্রেড_সিএসভিতে আসল বাধা, ডিস্কটি মোটেই নয়।

আমার যুক্ত করা উচিত আমি দ্রুত ভিডিও কার্ড বাসে এসএসডি ব্যবহার করছি, এসটিএ 6 বাসে কোনও স্পিনিং এইচডি নয়, 16 সিপিইউ কোর।

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

সমান্তরাল বাইট অফসেট ট্রিক ব্যবহার করে নীচে কয়েকটি উদাহরণ বেনমার্ক দেওয়া হল:

আমি 2 টি ফাইল ব্যবহার করি: এইচআইজিজিএসসিএসভি 8 জিবি। এটি ইউসিআই মেশিন লার্নিংয়ের সংগ্রহস্থল থেকে এসেছে। all_bin .csv 40.4 গিগাবাইট এবং আমার বর্তমান প্রকল্প থেকে। আমি 2 টি প্রোগ্রাম ব্যবহার করি: জিএনইউ ডাব্লুসি প্রোগ্রাম যা লিনাক্স সহ আসে এবং খাঁটি পাইথন ফাস্ট্রেড.পি প্রোগ্রাম যা আমি বিকাশ করি।

HP-Z820:/mnt/fastssd/fast_file_reader$ ls -l /mnt/fastssd/nzv/HIGGS.csv
-rw-rw-r-- 1 8035497980 Jan 24 16:00 /mnt/fastssd/nzv/HIGGS.csv

HP-Z820:/mnt/fastssd$ ls -l all_bin.csv
-rw-rw-r-- 1 40412077758 Feb  2 09:00 all_bin.csv

ga@ga-HP-Z820:/mnt/fastssd$ time python fastread.py --fileName="all_bin.csv" --numProcesses=32 --balanceFactor=2
2367496

real    0m8.920s
user    1m30.056s
sys 2m38.744s

In [1]: 40412077758. / 8.92
Out[1]: 4530501990.807175

এটি প্রায় 4.5 গিগাবাইট / এস, বা 45 জিবি / গুলি, ফাইল স্লিপিং গতি। এটি কোনও স্পিনিং হার্ড ডিস্ক নয়, আমার বন্ধু। এটি আসলে একটি স্যামসাং প্রো 950 এসএসডি।

নিখুঁত সি সংকলিত প্রোগ্রাম, gnu ডাব্লুসি দ্বারা লাইন গণনা করা একই গতির জন্য নীচের গতি মাপদণ্ড রয়েছে।

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

HP-Z820:/mnt/fastssd$ time wc -l all_bin.csv
2367496 all_bin.csv

real    0m8.807s
user    0m1.168s
sys 0m7.636s


HP-Z820:/mnt/fastssd/fast_file_reader$ time python fastread.py --fileName="HIGGS.csv" --numProcesses=16 --balanceFactor=2
11000000

real    0m2.257s
user    0m12.088s
sys 0m20.512s

HP-Z820:/mnt/fastssd/fast_file_reader$ time wc -l HIGGS.csv
11000000 HIGGS.csv

real    0m1.820s
user    0m0.364s
sys 0m1.456s

উপসংহার: একটি গিগাবাইট সি প্রোগ্রামের তুলনায় খাঁটি অজগর প্রোগ্রামের জন্য গতি ভাল। যাইহোক, সি প্রোগ্রামের উপর খাঁটি অজগর প্রোগ্রামটি ব্যবহার করার পক্ষে এটি যথেষ্ট ভাল নয়, অন্তত অন্তর্বাসের উদ্দেশ্যে। সাধারণত কৌশলটি অন্য ফাইল প্রসেসিংয়ের জন্য ব্যবহার করা যেতে পারে, তাই এই অজগর কোডটি এখনও ভাল।

প্রশ্ন: রেজেজকে শুধুমাত্র একবারে সংকলন করে সমস্ত শ্রমিকের কাছে দিয়ে দিলে গতি উন্নত হবে? উত্তর: রেজেক্স প্রাক-সংকলন এই অ্যাপ্লিকেশনটিতে সহায়তা করে না। আমি মনে করি এর কারণ হ'ল প্রক্রিয়া সিরিয়ালাইজেশন এবং সমস্ত শ্রমিকের জন্য সৃষ্টির ওভারহেড প্রাধান্য পেয়েছে।

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

খুঁজে বের কর:

HP-Z820:/mnt/fastssd/fast_file_reader$ time python fastread.py --fileName="HIGGS.csv" --numProcesses=16 --balanceFactor=2
11000000

real    0m2.256s
user    0m10.696s
sys 0m19.952s

HP-Z820:/mnt/fastssd/fast_file_reader$ time python fastread.py --fileName="HIGGS.csv" --numProcesses=1 --balanceFactor=1
11000000

real    0m17.380s
user    0m11.124s
sys 0m6.272s

ওহ হ্যাঁ, হ্যাঁ তা করে। সমান্তরাল ফাইল পড়া বেশ ভাল কাজ করে works আচ্ছা আপনি সেখানে যান!

পুনশ্চ. যদি আপনারা কেউ কেউ জানতে চেয়েছিলেন যে, একক কর্মী প্রক্রিয়াটি ব্যবহার করার সময় যদি ব্যালেন্সফ্যাক্টর 2 হয়? আচ্ছা, এটা ভয়াবহ:

HP-Z820:/mnt/fastssd/fast_file_reader$ time python fastread.py --fileName="HIGGS.csv" --numProcesses=1 --balanceFactor=2
11000000

real    1m37.077s
user    0m12.432s
sys 1m24.700s

ফাস্ট্রেড.পি পাইথন প্রোগ্রামের মূল অংশগুলি:

fileBytes = stat(fileName).st_size  # Read quickly from OS how many bytes are in a text file
startByte, endByte = PartitionDataToWorkers(workers=numProcesses, items=fileBytes, balanceFactor=balanceFactor)
p = Pool(numProcesses)
partialSum = p.starmap(ReadFileSegment, zip(startByte, endByte, repeat(fileName))) # startByte is already a list. fileName is made into a same-length list of duplicates values.
globalSum = sum(partialSum)
print(globalSum)


def ReadFileSegment(startByte, endByte, fileName, searchChar='\n'):  # counts number of searchChar appearing in the byte range
    with open(fileName, 'r') as f:
        f.seek(startByte-1)  # seek is initially at byte 0 and then moves forward the specified amount, so seek(5) points at the 6th byte.
        bytes = f.read(endByte - startByte + 1)
        cnt = len(re.findall(searchChar, bytes)) # findall with implicit compiling runs just as fast here as re.compile once + re.finditer many times.
    return cnt

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

ধন্যবাদ: আরনো এবং ক্লিফ এবং এইচ 2 ও কর্মীদের দ্বারা তাদের দুর্দান্ত সফ্টওয়্যার এবং নির্দেশমূলক ভিডিওগুলির জন্য ওপেন-সোর্স এইচ 2 ও প্রকল্প, যা আমাকে এই খাঁটি পাইথনের উচ্চ পারফরম্যান্স সমান্তরাল বাইট অফসেট পাঠকের উপরের মতো দেখিয়েছে above এইচ 2 ও জাভা ব্যবহার করে সমান্তরাল ফাইল রিডিং করে, পাইথন এবং আর প্রোগ্রাম দ্বারা কল করা যায় এবং বড় সিএসভি ফাইলগুলি পড়ার সময় গ্রহের যেকোন চেয়ে দ্রুত পাগল।


মূলত সমান্তরাল খণ্ডগুলি এটি। এছাড়াও, আমি আশা করি এসএসডি এবং ফ্ল্যাশ এই কৌশলটি সহ একমাত্র উপযুক্ত storage স্পিনিং এইচডি সামঞ্জস্য হওয়ার সম্ভাবনা কম।
জেফ্রি অ্যান্ডারসন

1
ওএস ক্যাচিং ডিস্ক ফাইলগুলির জন্য আপনি কীভাবে অ্যাকাউন্ট করবেন?
জেমস থমাসমুন 1979

5

ক্যাটরিল্লেক্স একটি ফাইল খোলার ও পড়ার উপায় সরবরাহ করেছিল।

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

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

আপনার ফাইলগুলি কত লাইনে আছে এবং কোন ধরণের মেশিনে (মেমো ও সিপিইউ পাওয়ার) আপনার অ্যালগরিদমটি চালাতে হবে এবং সহ্য হওয়া রানটাইমটি কী?

কোডটি দেখতে এমন হবে:

with f_outer as open(input_file, 'r'):
    for line_outer in f_outer:
        with f_inner as open(input_file, 'r'):
            for line_inner in f_inner:
                compute_distance(line_outer, line_inner)

তবে প্রশ্নগুলি হ'ল আপনি কীভাবে দূরত্বগুলি সংরক্ষণ করেন (ম্যাট্রিক্স?) ​​এবং আপনি যেমন প্রক্রিয়াজাতকরণের জন্য বাইরের_লাইন প্রস্তুত করার, বা পুনরায় ব্যবহারের জন্য কিছু মধ্যবর্তী ফলাফলগুলি ক্যাশে করার সুবিধা অর্জন করতে পারেন।


আমার বক্তব্যটি এই পোস্টটিতে প্রশ্নের উত্তর নেই, আরও কিছু প্রশ্ন রয়েছে! আইএমও এটি মন্তব্য হিসাবে ভাল উপযুক্ত হবে।
ক্যাট্রিয়েল

1
@ ক্যাটারিআলেক্স: এর। স্ট্রেঞ্জ। আপনি প্রকৃত প্রশ্নের সাথে মানিয়ে নিতে নিজের উত্তরটি প্রসারিত, নেস্টেড লুপগুলি দেখেছেন? আমি আমার উত্তরগুলি থেকে আমার প্রশ্নগুলি এখানে সরিয়ে ফেলতে পারি, এবং এটিকে একটি - আংশিক হলেও - উত্তর হিসাবে সরবরাহের পক্ষে পর্যাপ্ত সামগ্রী রয়েছে। আপনি যদি নিজের উত্তরটি সম্পাদিত করতে চান তবে নেস্টেড লুপের উদাহরণটি অন্তর্ভুক্ত করুন - যা প্রশ্ন দ্বারা স্পষ্টভাবে জিজ্ঞাসা করা হয়েছিল - এবং তারপরে আমি খুশিতে আমার নিজের উত্তরটি মুছে ফেলতে পারি। তবে ডাউনওয়েট এমন জিনিস যা আমি মোটেও পাই না।
সিএফআই

যথেষ্ট ফর্সা; আমি প্রশ্নের উত্তর হিসাবে লুপের জন্য নেস্টেডকে প্রকৃতপক্ষে দেখছি না তবে আমার ধারণা এটি প্রাথমিকভাবে লক্ষ্য করে এটি বেশ দৃ .়ভাবে লক্ষ্যযুক্ত targeted ডাউনভোট সরানো হয়েছে।
ক্যাট্রিয়েল

3
#Using a text file for the example
with open("yourFile.txt","r") as f:
    text = f.readlines()
for line in text:
    print line
  • পড়ার জন্য আপনার ফাইলটি খুলুন (আর)
  • পুরো ফাইলটি পড়ুন এবং প্রতিটি লাইন একটি তালিকায় সংরক্ষণ করুন (পাঠ্য)
  • প্রতিটি লাইন মুদ্রণ তালিকা মাধ্যমে লুপ।

যদি আপনি চান, উদাহরণস্বরূপ, 10 এর চেয়ে বেশি দৈর্ঘ্যের জন্য একটি নির্দিষ্ট লাইনটি পরীক্ষা করতে, আপনি ইতিমধ্যে যা পেয়েছেন তার সাথে কাজ করুন।

for line in text:
    if len(line) > 10:
        print line

1
এই প্রশ্নের জন্য সেরা নয়, তবে আপনি যা খুঁজছেন সে ক্ষেত্রে এই কোডটি মূলত কার্যকর is "স্লুরপিং" (একবারে পুরো ফাইলটি পড়া)। এটি আমার ঘটনা এবং গুগল আমাকে এখানে পেয়েছে। +1 টি। এছাড়াও, পারমাণবিকতার জন্য, বা আপনি যদি লুপে সময় গ্রহণের প্রক্রিয়াজাতকরণটি সম্পূর্ণ ফাইলটি পড়তে দ্রুত শেষ করতে পারেন
এনটিজি

1
এছাড়াও কোডটি কিছুটা উন্নত করা হয়েছে: ১. এর পরে বন্ধ করার দরকার নেই: ( ডকস.পিথন.আর / ২ / টিউটোরিয়াল / ইনপুটআউটপুট.ইচটিএমএল , "কীওয়ার্ড সহ ব্যবহার করা ভাল অভ্যাস ...") 2 এর জন্য অনুসন্ধান করুন ফাইলটি পড়ার পরে পাঠ্য প্রক্রিয়া করা যেতে পারে (লুপের সাথে বাইরে ....)
এনটিজি

2

ফাইল ইনপুট। ইনপুট () এর জন্য পাইথন ডকুমেন্টেশন থেকে :

তালিকাভুক্ত সমস্ত ফাইলের লাইনটি পুনরাবৃত্তি করে sys.argv[1:], sys.stdinতালিকাটি খালি থাকলে ডিফল্ট

আরও, ফাংশনটির সংজ্ঞাটি হ'ল:

fileinput.FileInput([files[, inplace[, backup[, mode[, openhook]]]]])

লাইনের মধ্যে পড়া, এটি আমাকে বলে যে filesএটি একটি তালিকা হতে পারে যাতে আপনার মতো কিছু থাকতে পারে:

for each_line in fileinput.input([input_file, input_file]):
  do_something(each_line)

আরও তথ্যের জন্য এখানে দেখুন


2

আমি ডিফল্ট ফাইল লোডিংটি ভয়ঙ্করভাবে ধীর হওয়ায় ব্যবহার না করার জন্য দৃ strongly়ভাবে পরামর্শ দিচ্ছি। আপনাকে নম্পি ফাংশন এবং আইওপ্রো ফাংশনগুলি দেখতে হবে (উদাঃ numpy.loadtxt ())।

http://docs.scipy.org/doc/numpy/user/basics.io.genfromtxt.html

https://store.continuum.io/cshop/iopro/

তারপরে আপনি নিজের জুটিবদ্ধ ক্রিয়াকলাপটিকে খণ্ডগুলিতে ভাঙ্গতে পারেন:

import numpy as np
import math

lines_total = n    
similarity = np.zeros(n,n)
lines_per_chunk = m
n_chunks = math.ceil(float(n)/m)
for i in xrange(n_chunks):
    for j in xrange(n_chunks):
        chunk_i = (function of your choice to read lines i*lines_per_chunk to (i+1)*lines_per_chunk)
        chunk_j = (function of your choice to read lines j*lines_per_chunk to (j+1)*lines_per_chunk)
        similarity[i*lines_per_chunk:(i+1)*lines_per_chunk,
                   j*lines_per_chunk:(j+1)*lines_per_chunk] = fast_operation(chunk_i, chunk_j) 

এটি উপাদানগুলিতে উপাদানগুলি করার চেয়ে খণ্ডগুলিতে ডেটা লোড করা এবং তারপরে ম্যাট্রিক্স অপারেশন করা প্রায় সবসময়ই দ্রুত হয় !!


0

সর্বশেষ পজিশন থেকে বড় ফাইল পড়তে হবে?

আমি দিনের মধ্যে বেশ কয়েকবার অ্যাপাচি অ্যাক্সেস.লগ ফাইলটি কাটতে একটি স্ক্রিপ্ট তৈরি করেছি। সুতরাং আমার শেষ নির্বাহের সময় শেষ পংক্তিতে একটি অবস্থান কার্সার সেট করা দরকার । এই লক্ষ্যে, আমি ব্যবহার করেছি file.seek()এবংfile.seek() পদ্ধতিগুলি যা কার্সারে ফাইলে সংরক্ষণের অনুমতি দেয়।

আমার কোড:

ENCODING = "utf8"
CURRENT_FILE_DIR = os.path.dirname(os.path.abspath(__file__))

# This file is used to store the last cursor position
cursor_position = os.path.join(CURRENT_FILE_DIR, "access_cursor_position.log")

# Log file with new lines
log_file_to_cut = os.path.join(CURRENT_FILE_DIR, "access.log")
cut_file = os.path.join(CURRENT_FILE_DIR, "cut_access", "cut.log")

# Set in from_line 
from_position = 0
try:
    with open(cursor_position, "r", encoding=ENCODING) as f:
        from_position = int(f.read())
except Exception as e:
    pass

# We read log_file_to_cut to put new lines in cut_file
with open(log_file_to_cut, "r", encoding=ENCODING) as f:
    with open(cut_file, "w", encoding=ENCODING) as fw:
        # We set cursor to the last position used (during last run of script)
        f.seek(from_position)
        for line in f:
            fw.write("%s" % (line))

    # We save the last position of cursor for next usage
    with open(cursor_position, "w", encoding=ENCODING) as fw:
        fw.write(str(f.tell()))

-2

বড় ফাইল পড়ার সর্বোত্তম উপায়, লাইন বাই লাইন অজগর গণনা ফাংশনটি ব্যবহার করা

with open(file_name, "rU") as read_file:
    for i, row in enumerate(read_file, 1):
        #do something
        #i in line of that line
        #row containts all data of that line

3
কেন গণনার ব্যবহার আরও ভাল হয়? গৃহীত উত্তরের একমাত্র উপকারিতা হ'ল আপনি একটি সূচক পান, যা অপির প্রয়োজন হয় না এবং আপনি কোডটি কম পঠনযোগ্য করে তুলছেন।
ফুয়াস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.