2016-02-23 4 views
5

मैं एक एसक्यूएल तालिका है जो मैं एक पांडा डेटा फ्रेम, निम्नलिखित संरचना है कि के रूप में में पढ़ सकते हैं:एक लंबी तालिका से स्पार्सडेटाफ्रेम को कुशलतापूर्वक कैसे बनाएं?

user_id value 
1   100 
1   200 
2   100 
4   200 

यह एक मैट्रिक्स का प्रतिनिधित्व है, जिसके लिए सभी मूल्यों 1 हैं या 0. घने इस मैट्रिक्स के प्रतिनिधित्व इस प्रकार दिखाई देगा:

100 200 
1 1 1 
2 1 0 
4 0 1 

आम तौर पर, इस रूपांतरण आप धुरी का उपयोग कर सकते करने के लिए है, लेकिन पहले तालिका में दसियों या पंक्तियों के लाखों लोगों के सैकड़ों के साथ मेरे मामले में एक एक बड़ा घने मैट्रिक्स पूर्ण हो जाता है शून्य के लिए खींचने के लिए महंगा है। आप इसे स्पैस में परिवर्तित कर सकते हैं, लेकिन इसे प्राप्त करने के लिए बहुत सारे संसाधनों की आवश्यकता है।

अभी मैं प्रत्येक उपयोगकर्ता_आईडी, सॉर्टिंग के लिए पंक्ति संख्या असाइन करने के लिए एक समाधान पर काम कर रहा हूं, और फिर स्पैससेटाफ्रेम में पुन: संयोजन करने से पहले 'मान' कॉलम को स्पैर्ससेरीज़ में विभाजित कर रहा हूं। क्या कोई बेहतर तरीका है?

+0

मैंने SO पर स्पैरसेरीज़ की अधिक चर्चा नहीं देखी है। मैंने उस और 'scipy' 'sparse' matrices के बीच आगे और आगे स्थानांतरित करने के कुछ प्रश्नों का उत्तर दिया है। मेरी धारणा यह है कि पांडों की 'स्पैस' संरचना अभी भी विकास में है। – hpaulj

+0

मुझे आपके उत्तर जैसे कुछ मिल गए हैं http://stackoverflow.com/questions/34181494/populate-a-pandas-sparsedataframe-from-a-scipy-sparse-coo-matrix समस्या यह है पैमाने पर प्रतीत नहीं होता है। अभी मैं एक सीएससी मैट्रिक्स को बदलने की कोशिश कर रहा हूं जो कि 40,000 x 15,000 है और यह 30 मिनट से अधिक समय तक चल रहा है। –

उत्तर

1

मैं एक समाधान पर पहुंचा, हालांकि थोड़ा अपूर्ण एक।

कॉलम से मैन्युअल रूप से कई पांडस स्पैरसेरीज़ बनाने के लिए क्या कर सकता है, उन्हें एक ताना में जोड़ दें, और उसके बाद उस डेटा को डेटाफ्रेम (स्पैसडाटाफ्रेम नहीं) पर डालें। SparseDataFrame के रूप में कास्टिंग वर्तमान में एक अपरिपक्व कन्स्ट्रक्टर को हिट करता है, जो पूरे ऑब्जेक्ट को घने में घुलता है और फिर इनपुट के बावजूद स्पैस फॉर्म में वापस ले जाता है। एक पारंपरिक डेटाफ्रेम में स्पैरसेरीज़ का निर्माण, हालांकि, दुर्लभता को बनाए रखता है लेकिन एक व्यवहार्य और अन्यथा डेटाफ्रेम ऑब्जेक्ट बनाता है।

प्रदर्शन के मुकाबले स्पष्टता के लिए और अधिक लिखा गया है, यह एक प्रदर्शन है। अपने स्वयं के कार्यान्वयन के साथ एक अंतर यह है कि मैंने लूप के बजाए एक स्पैम वैक्टर के रूप में स्पैस वैक्टरों का निर्देश बनाया है।

import pandas 
import numpy 

df = pandas.DataFrame({'user_id':[1,2,1,4],'value':[100,100,200,200]}) 

# Get unique users and unique features 
num_rows = len(df['user_id'].unique()) 
num_features = len(df['value'].unique()) 
unique_users = df['user_id'].unique().copy() 
unique_features = df['value'].unique().copy() 
unique_users.sort() 
unique_features.sort() 


# assign each user_id to a row_number 
user_lookup = pandas.DataFrame({'uid':range(num_rows), 'user_id':unique_users}) 


vec_dict = {} 

# Create a sparse vector for each feature 
for i in range(num_features): 
    users_with_feature = df[df['value']==unique_features[i]]['user_id'] 

    uid_rows = user_lookup[user_lookup['user_id'].isin(users_with_feature)]['uid'] 

    vec = numpy.zeros(num_rows) 
    vec[uid_rows] = 1 

    sparse_vec = pandas.Series(vec).to_sparse(fill_value=0) 

    vec_dict[unique_features[i]] = sparse_vec 


my_pandas_frame = pandas.DataFrame(vec_dict)  
my_pandas_frame = my_pandas_frame.set_index(user_lookup['user_id']) 

परिणाम:

>>> my_pandas_frame 
     100 200 
user_id   
1   1 1 
2   1 0 
4   0 1 

>>> type(my_pandas_frame) 
<class 'pandas.core.frame.DataFrame'> 

>>> type(my_pandas_frame[100]) 
<class 'pandas.sparse.series.SparseSeries'> 

पूरा, लेकिन अभी भी विरल। कुछ चेतावनी हैं, यदि आप एक साधारण प्रतिलिपि करते हैं या जगह नहीं लेते हैं तो यह स्वयं को भूल जाएगा और घने को पुन: प्रयास करने का प्रयास करेगा, लेकिन मेरे उद्देश्यों के लिए मैं इसके साथ बहुत खुश हूं।

संबंधित मुद्दे