मैं नियमित रूप से इस फैशन में दसियों गीगाबाइट डेटा का उपयोग करता हूं। मेरे पास डिस्क पर टेबल हैं जिन्हें मैं प्रश्नों के माध्यम से पढ़ता हूं, डेटा बनाता हूं और वापस जोड़ता हूं।
अपने डेटा को स्टोर करने के तरीके के बारे में कई सुझावों के लिए डॉक्स और इस थ्रेड में देर से पढ़ने लायक है।
विवरण जो आपके डेटा को स्टोर करने के तरीके को प्रभावित करेगा, जैसे:
जितना हो सके उतना विवरण दें; और मैं एक संरचना विकसित करने में आपकी सहायता कर सकता हूं।
- डेटा का आकार, # पंक्तियों, स्तंभों, स्तंभों के प्रकार; क्या आप जोड़ रहे हैं, या सिर्फ कॉलम?
- सामान्य संचालन कैसा दिखेगा। उदा. पंक्तियों और विशिष्ट स्तंभों के एक समूह का चयन करने के लिए स्तंभों पर एक प्रश्न करें, फिर एक ऑपरेशन (इन-मेमोरी) करें, नए कॉलम बनाएं, इन्हें सहेजें।
(खिलौने का उदाहरण देने से हम अधिक विशिष्ट अनुशंसाएं प्रदान कर सकते हैं। ) - उस प्रोसेसिंग के बाद आप क्या करते हैं? क्या चरण 2 तदर्थ है, या दोहराने योग्य है?
- फ्लैट फ़ाइलें इनपुट करें:जीबी में कितने, मोटे कुल आकार। ये कैसे व्यवस्थित हैं उदा। अभिलेखों द्वारा? क्या हर एक में अलग-अलग फ़ील्ड होते हैं, या क्या उनके पास प्रत्येक फ़ाइल में सभी फ़ील्ड के साथ प्रति फ़ाइल कुछ रिकॉर्ड होते हैं?
- क्या आपने कभी मानदंड के आधार पर पंक्तियों (रिकॉर्ड) के सबसेट का चयन किया है (उदाहरण के लिए फ़ील्ड A> 5 वाली पंक्तियों का चयन करें)? और फिर कुछ करें, या आप सभी रिकॉर्ड्स के साथ ए, बी, सी फ़ील्ड्स का चयन करें (और फिर कुछ करें)?
- क्या आप अपने सभी स्तंभों (समूहों में) पर 'काम' करते हैं, या क्या कोई अच्छा अनुपात है जिसका उपयोग आप केवल रिपोर्ट के लिए कर सकते हैं (उदाहरण के लिए आप डेटा को इधर-उधर रखना चाहते हैं, लेकिन उसमें खींचने की आवश्यकता नहीं है अंतिम परिणाम समय तक कॉलम स्पष्टीकरण)?
समाधान
सुनिश्चित करें कि आपके पास पांडा हैं कम से कम 0.10.1
स्थापित।
पुनरावृति फ़ाइलें खंड-दर-खंड और एकाधिक तालिका क्वेरी पढ़ें।
चूंकि पाइटेबल्स को पंक्ति-वार संचालित करने के लिए अनुकूलित किया गया है (जिस पर आप क्वेरी करते हैं), हम फ़ील्ड के प्रत्येक समूह के लिए एक टेबल तैयार करेंगे। इस प्रकार फ़ील्ड के एक छोटे समूह का चयन करना आसान है (जो एक बड़ी तालिका के साथ काम करेगा, लेकिन इसे इस तरह से करना अधिक कुशल है ... मुझे लगता है कि मैं भविष्य में इस सीमा को ठीक करने में सक्षम हो सकता हूं ... यह है किसी भी तरह अधिक सहज ज्ञान युक्त):
(निम्नलिखित छद्म कोड है।)
import numpy as np
import pandas as pd
# create a store
store = pd.HDFStore('mystore.h5')
# this is the key to your storage:
# this maps your fields to a specific group, and defines
# what you want to have as data_columns.
# you might want to create a nice class wrapping this
# (as you will want to have this map and its inversion)
group_map = dict(
A = dict(fields = ['field_1','field_2',.....], dc = ['field_1',....,'field_5']),
B = dict(fields = ['field_10',...... ], dc = ['field_10']),
.....
REPORTING_ONLY = dict(fields = ['field_1000','field_1001',...], dc = []),
)
group_map_inverted = dict()
for g, v in group_map.items():
group_map_inverted.update(dict([ (f,g) for f in v['fields'] ]))
फाइलों में पढ़ना और भंडारण बनाना (अनिवार्य रूप से वही करना जो append_to_multiple
. है करता है):
for f in files:
# read in the file, additional options may be necessary here
# the chunksize is not strictly necessary, you may be able to slurp each
# file into memory in which case just eliminate this part of the loop
# (you can also change chunksize if necessary)
for chunk in pd.read_table(f, chunksize=50000):
# we are going to append to each table by group
# we are not going to create indexes at this time
# but we *ARE* going to create (some) data_columns
# figure out the field groupings
for g, v in group_map.items():
# create the frame for this group
frame = chunk.reindex(columns = v['fields'], copy = False)
# append it
store.append(g, frame, index=False, data_columns = v['dc'])
अब आपके पास फ़ाइल में सभी टेबल हैं (वास्तव में आप उन्हें अलग-अलग फाइलों में स्टोर कर सकते हैं यदि आप चाहें, तो आपको फ़ाइल नाम को group_map में जोड़ना होगा, लेकिन शायद यह आवश्यक नहीं है)।
इस प्रकार आप कॉलम प्राप्त करते हैं और नए बनाते हैं:
frame = store.select(group_that_I_want)
# you can optionally specify:
# columns = a list of the columns IN THAT GROUP (if you wanted to
# select only say 3 out of the 20 columns in this sub-table)
# and a where clause if you want a subset of the rows
# do calculations on this frame
new_frame = cool_function_on_frame(frame)
# to 'add columns', create a new group (you probably want to
# limit the columns in this new_group to be only NEW ones
# (e.g. so you don't overlap from the other tables)
# add this info to the group_map
store.append(new_group, new_frame.reindex(columns = new_columns_created, copy = False), data_columns = new_columns_created)
जब आप पोस्ट_प्रोसेसिंग के लिए तैयार हों:
# This may be a bit tricky; and depends what you are actually doing.
# I may need to modify this function to be a bit more general:
report_data = store.select_as_multiple([groups_1,groups_2,.....], where =['field_1>0', 'field_1000=foo'], selector = group_1)
data_columns के बारे में, आपको वास्तव में कोई भी . परिभाषित करने की आवश्यकता नहीं है डेटा_कॉलम; वे आपको कॉलम के आधार पर पंक्तियों को उप-चयन करने की अनुमति देते हैं। उदा. कुछ इस तरह:
store.select(group, where = ['field_1000=foo', 'field_1001>0'])
अंतिम रिपोर्ट निर्माण चरण में वे आपके लिए सबसे दिलचस्प हो सकते हैं (अनिवार्य रूप से एक डेटा कॉलम को अन्य कॉलम से अलग किया जाता है, जो कुछ हद तक दक्षता को प्रभावित कर सकता है यदि आप बहुत कुछ परिभाषित करते हैं)।
आप यह भी करना चाहेंगे:
- एक फ़ंक्शन बनाएं जो फ़ील्ड की एक सूची लेता है, समूहों को समूहों_मैप में देखता है, फिर इनका चयन करता है और परिणामों को जोड़ता है ताकि आपको परिणामी फ्रेम मिल सके (यह अनिवार्य रूप से select_as_multiple करता है)। इस तरह संरचना आपके लिए काफी पारदर्शी होगी।
- कुछ डेटा कॉलम पर अनुक्रमित (पंक्ति-सबसेटिंग को बहुत तेज़ बनाता है)।
- संपीड़न सक्षम करें।
जब आपके कोई प्रश्न हों तो मुझे बताएं!