मेरे पास 2 कॉलम वाले कई डेटा सेट हैं: ID और ActivityDate। डेटासेट में एक ID+ActivityDate अद्वितीय होता है। प्रत्येक डेटासेट लगभग 35 मिलियन रिकॉर्ड लंबा है। 60+ डेटासेट हैं।

मेरा वांछित आउट पुट मूल रूप से ID, FirstActivityDate और LastActivityDate है। यह मूल रूप से मानचित्र का छोटा हिस्सा है/नौकरी को कम करता है।

मेरा पहला प्रयास मूल रूप से पहले डेटासेट को पढ़ना था, बेस लाइन स्थापित करना, और फिर जैसे ही मैंने अगला डेटासेट पढ़ा, मैं LastActivityDate की तुलना और अद्यतन करने के लिए एक फ़ोरैच करता हूं। यद्यपि उपयोग की गई मेमोरी बहुत स्वीकार्य थी (2 जीबी पर स्पाइकिंग लेकिन लगातार 1.25 जीबी से कम), इसमें बहुत अधिक समय लगा। मैंने गणना की, परिणाम सेट लगभग 1.5 जीबी लंबा होना चाहिए, इसलिए यह स्थानीय-स्मृति प्रबंधनीय है।

for x in files:
    parsedData = parseFile(x)
    dt = parsedData[0]
    cards = parsedData[1]
    for card in cards:
        #num = int(card[:16])
        if card in result:
            result[card].lastRecharged = dt
        else:
            result[card]=CreditCard(dt)

उस लाइन पर टिप्पणी करते हुए #num = int(card[:16]) ने लूप निष्पादन को प्रति फ़ाइल 30 सेकंड तक कम कर दिया (मूल लगभग 150 सेकंड था), लेकिन अब मेमोरी नियंत्रण से बाहर हो गई है। फ़ाइल पार्सिंग मूल रूप से एक फ़ाइल पढ़ी जाती है, जिसमें 1 सेकंड से भी कम समय लगता है।

मेरा दूसरा प्रयास पांडा का उपयोग कर रहा था, लेकिन मैं डेटासेट को जिस तरह से चाहता हूं उसे मर्ज नहीं कर सका। मुझे कहना होगा कि मैं पांडा में कुशल नहीं हूँ।

क्या कोई तीसरा विकल्प है?

0
Leonardo 20 फरवरी 2020, 16:35
1
डेटाबेस का उपयोग करें? इतनी मात्रा में डेटा मर्ज करने की आवश्यकता से बचने के लिए मानचित्र के "मानचित्र" भाग को बदलें/नौकरी कम करें?
 – 
mkrieger1
20 फरवरी 2020, 16:38
2
और मैं शर्त लगाता हूं कि डेटाबेस कोड लिखने और अनुकूलित करने वाले कई इंजीनियर पाइथन प्रोग्राम की तुलना में ऐसी चीजों को अधिक कुशलता से कार्यान्वित करने में सक्षम थे।
 – 
mkrieger1
20 फरवरी 2020, 16:47
4
"मेरे पास डेटाबेस नहीं है" - आपके पास हमेशा पाइथन के साथ SQLite है!
 – 
AKX
20 फरवरी 2020, 16:59
2
क्या आप अपने पहले प्रयास का कोड दिखा सकते हैं जिसमें बहुत अधिक समय लगा? (साथ ही, कितना समय बहुत लंबा था और कब तक पर्याप्त तेज़ होगा?)
 – 
Ry-
20 फरवरी 2020, 17:00
1
कॉर्पोरेट सुरक्षा नीतियां
 – 
Leonardo
20 फरवरी 2020, 17:03

2 जवाब

मैं अपने लक्ष्य के काफी करीब पहुंच गया।

मुट्ठी मैंने मेमोरी में रीडिंग और पार्सिंग को समवर्ती बनाया और multithreading.pool का उपयोग करके बैचों में, प्रत्येक परिणाम को एक कतार में धकेल दिया गया। प्रत्येक पूल में लगातार 3 फाइलें होंगी, 4 pools में साइकिल चलाना। 5 वें पूल में, मैं गैर-आवर्तक कुंजी (कार्ड) छोड़ने वाले शब्दकोशों को पूर्व-मर्ज करता हूं। फिर 6 वें पूल में मैं अंतिम विलय करता हूं।

मेरी स्थानीय मशीन पर पूरी प्रक्रिया में लगभग 75 सेकंड लगते हैं। पूरी चीज 4GB से अधिक रैम की खपत करती है, जो आदर्श नहीं है, लेकिन प्रबंधनीय है।

0
Leonardo 26 फरवरी 2020, 23:25

IIUC आप प्रत्येक ID के लिए पहले और अंतिम ActivityDate में रुचि रखते हैं यदि ऐसा है तो आप dask का उपयोग कर सकते हैं। मान लें कि आपकी सभी फ़ाइल csv हैं और वे data नामक फ़ोल्डर में संग्रहीत हैं।

import dask.dataframe as dd
import pandas as pd

df = dd.read_csv("data/*.csv")

# convert ActivityDate to datetime
df["ActivityDate"] = df["ActivityDate"].astype("M8[us]")

# use aggregate
out = df.groupby("ID")\
        .agg({"ActivityDate":["min", "max"]})\
        .compute()

out.columns = ["_".join(col) for col in out.columns]
out = out.reset_index()
out = out.rename(columns={'ActivityDate_min':"FirstActivityDate",
                          'ActivityDate_max':"LastActivityDate"})
0
rpanai 26 फरवरी 2020, 23:49