2017-01-05 7 views
9

मैं एक पांडा डेटाफ्रेम के साथ काम कर रहा हूं जो एक ग्राफ का प्रतिनिधित्व करता है। डेटाफ्रेम को मल्टीइंडेक्स द्वारा अनुक्रमित किया जाता है जो नोड एंडपॉइंट्स को इंगित करता है।पंपस मल्टी इंडेक्स लुकअप न्यूमरे एरेज़

सेटअप:

import pandas as pd 
import numpy as np 
import itertools as it 
edges = list(it.combinations([1, 2, 3, 4], 2)) 

# Define a dataframe to represent a graph 
index = pd.MultiIndex.from_tuples(edges, names=['u', 'v']) 
df = pd.DataFrame.from_dict({ 
    'edge_id': list(range(len(edges))), 
    'edge_weight': np.random.RandomState(0).rand(len(edges)), 
}) 
df.index = index 
print(df) 
## -- End pasted text -- 
    edge_id edge_weight 
u v      
1 2  0  0.5488 
    3  1  0.7152 
    4  2  0.6028 
2 3  3  0.5449 
    4  4  0.4237 
3 4  5  0.6459 

मैं ग्राफ बढ़त सबसेट का उपयोग कर, जिसके कारण मैं एक MultiIndex उपयोग करने के लिए चुन लिया है में सूचकांक करने में सक्षम होना चाहता हूँ। मैं इसे तब तक ठीक करने में सक्षम हूं जब तक df.loc पर इनपुट tuples की एक सूची है।

# Select subset of graph using list-of-tuple indexing 
edge_subset1 = [edges[x] for x in [0, 3, 2]] 
df.loc[edge_subset1] 
## -- End pasted text -- 
    edge_id edge_weight 
u v      
1 2  0  0.5488 
2 3  3  0.5449 
1 4  2  0.6028 

हालांकि, जब किनारों की सूची को एक numpy सरणी है (क्योंकि यह अक्सर है), या सूचियों की एक सूची, तो मैं df.loc संपत्ति उपयोग करने में असमर्थ होने लगते हैं।

# Why can't I do this if `edge_subset2` is a numpy array? 
edge_subset2 = np.array(edge_subset1) 
df.loc[edge_subset2] 
## -- End pasted text -- 
TypeError: unhashable type: 'numpy.ndarray' 

अगर मैं सब arr.tolist(), लेकिन यह एक उचित रूप में अलग त्रुटि में परिणाम सकता है यह ठीक हो जाएगा।

# Why can't I do this if `edge_subset2` is a numpy array? 
# or if `edge_subset3` is a list-of-lists? 
edge_subset3 = edge_subset2.tolist() 
df.loc[edge_subset3] 
## -- End pasted text -- 
TypeError: '[1, 2]' is an invalid key 

यह एक वास्तविक दर्द हर बार जब मैं एक सबसेट का चयन करना चाहते list(map(tuple, arr.tolist())) उपयोग करने के लिए है। यह अच्छा होगा अगर ऐसा करने का दूसरा तरीका था।

मुख्य हुए प्रश्न हैं:

  • मैं .loc के साथ एक numpy सरणी का उपयोग क्यों नहीं कर सकते हैं? क्या ऐसा इसलिए है क्योंकि हुड के तहत बहु-सूचकांक लेबल को स्थितित्मक सूचकांक में मैप करने के लिए एक शब्दकोश का उपयोग किया जा रहा है?

  • सूची-सूची-सूची एक अलग त्रुटि क्यों देती है? हो सकता है कि यह वास्तव में एक ही समस्या है, यह सिर्फ एक अलग तरीके से पकड़ा?

  • क्या मल्टी-इंडेक्स लेबलों की एक संख्यात्मक सरणी के साथ डेटाफ्रेम के उप-समूह को देखने के लिए कोई और (आदर्श कम-वर्बोज़) तरीका है जिसे मैं अनजान हूं?

+0

ध्यान दें कि 'df.edge_id [edge_subset2]' काम करता है - जिसका अर्थ है अनुक्रमण की यह शैली एक श्रृंखला पर समर्थित है लेकिन कुछ कारणों से डेटाफ्रेम नहीं है। विचित्र रूप से, 'df.edge_id.loc [edge_subset2]' भी विफल रहता है (किसी भी कारण से, क्योंकि यह 'loc' के बिना काम करता है)। मैं यहां पांडों को यह सबमिट करने का सुझाव देता हूं: https://github.com/pandas-dev/pandas/issues –

उत्तर

2

एक शब्दकोश कुंजी अपरिवर्तनीय है, मूल रूप से आप बहु-अनुक्रमणिका तक पहुंचने के लिए सूचियों की सूची का उपयोग क्यों नहीं कर सकते हैं।

loc का उपयोग कर बहु-अनुक्रमित डेटा तक पहुंचने में सक्षम होने के लिए आपको अपने numpy सरणी को टुपल्स की सूची में परिवर्तित करने की आवश्यकता है; tuples अपरिवर्तनीय हैं, एक ही रास्ता map उपयोग कर रहा है के रूप में आप

उल्लेख ऐसा करने के लिए आप नक्शे का उपयोग कर से बचने के लिए चाहते हैं और आप एक csv फ़ाइल के रूप में किनारों पढ़ रहे हैं, तो आप उन्हें एक डेटा फ्रेम में पढ़ सकता है तो साथ to_records का उपयोग करते हैं index विशेषता False करने के लिए सेट, एक और तरीका है ndarray से एक बहु सूचकांक बनाने के द्वारा किया जा सकता है, लेकिन आप यह इतना गुजर कि प्रत्येक स्तर सरणी

import pandas as pd 

df1 = df.loc[pd.MultiIndex.from_arrays(edge_subset2.T)] 


print(df1) 

#outputs 
      edge_id edge_weight 
------ --------- ------------- 
(1, 2)   0  0.548814 
(2, 3)   3  0.544883 
(1, 4)   2  0.602763 

मैंने पाया में एक सूची है से पहले सूची स्थानांतरित करने के लिए है पांडा दस्तावेज में लेख advanced multi-indexing बहुत उपयोगी

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