2017-05-19 10 views
6

मेरे पास डेटासेट है जिसमें 50k से अधिक नोड्स हैं और मैं उनसे संभव किनारों और समुदायों को निकालने का प्रयास कर रहा हूं। मैंने किन ग्राफों और समुदायों को देखने और पहचानने के लिए गेफी, साइटोस्केप, सॉनेट, नोडेक्सल जैसे कुछ ग्राफ टूल्स का उपयोग करने की कोशिश की लेकिन नोड सूची उन उपकरणों के लिए बहुत बड़ी है .. इसलिए मैं किनारे और समुदायों को सटीक बनाने के लिए स्क्रिप्ट लिखने की कोशिश कर रहा हूं । अन्य कॉलम कनेक्शन जीपीएस स्थानों के साथ डेटटाइम और एंड डेटटाइम शुरू होते हैं।नोड्स की सूची से एज और समुदायों को निकालें

इनपुट: क्रमांक, StartTime, endtime, gps1, gps2

0022d9064bc,1073260801,1073260803,819251,440006 
00022d9064bc,1073260803,1073260810,819213,439954 
00904b4557d3,1073260803,1073261920,817526,439458 
00022de73863,1073260804,1073265410,817558,439525 
00904b14b494,1073260804,1073262625,817558,439525 
00904b14b494,1073260804,1073265163,817558,439525 
00904b14b494,1073260804,1073263786,817558,439525 
00022d1406df,1073260807,1073260809,820428,438735 
00022d1406df,1073260807,1073260878,820428,438735 
00022d623dfe,1073260810,1073276346,819251,440006 
00022d7317d7,1073260810,1073276155,819251,440006 
00022d9064bc,1073260810,1073272525,819251,440006 
00022d9064bc,1073260810,1073260999,819251,440006 
00022d9064bc,1073260810,1073260857,819251,440006 
0030650c9eda,1073260811,1073260813,820356,439224 
00022d0e0cec,1073260813,1073262843,820187,439271 
00022d176cf3,1073260813,1073260962,817721,439564 
000c30d8d2e8,1073260813,1073260902,817721,439564 
00904b243bc4,1073260813,1073260962,817721,439564 
00904b2fc34d,1073260813,1073260962,817721,439564 
00904b52b839,1073260813,1073260962,817721,439564 
00904b9a5a51,1073260813,1073260962,817721,439564 
00904ba8b682,1073260813,1073260962,817721,439564 
00022d3be9cd,1073260815,1073261114,819269,439403 
00022d80381f,1073260815,1073261114,819269,439403 
00022dc1b09c,1073260815,1073261114,819269,439403 
00022d36a6df,1073260817,1073260836,820761,438607 
00022d36a6df,1073260817,1073260845,820761,438607 
003065d2d8b6,1073260817,1073267560,817735,439757 
00904b0c7856,1073260817,1073265149,817735,439757 
00022de73863,1073260825,1073260879,817558,439525 
00904b14b494,1073260825,1073260879,817558,439525 
00904b312d9e,1073260825,1073260879,817558,439525 
00022d15b1c7,1073260826,1073260966,820353,439280 
00022dcbe817,1073260826,1073260966,820353,439280 

मैं अनिर्दिष्ट भारित/अनिर्धारित ग्राफ लागू करने के लिए कोशिश कर रहा हूँ। कोडिंग के लिए सुझावों के साथ किसी भी मदद की अत्यधिक सराहना की जाती है।

अग्रिम

+0

यह निर्धारित करने के लिए मानदंड क्या है कि दो नोड्स के बीच किनारे मौजूद है या नहीं? –

+0

वही स्थान और उसी शुरुआत और समाप्ति समय के निकट –

+0

@huck_cussler समान स्थान और उसी शुरुआत और समाप्ति समय के निकट –

उत्तर

7

उपयोग पांडा धन्यवाद एक जोड़ो में नोड सूची है, जहां प्रत्येक पंक्ति अपने किनारे मानदंडों के आधार पर, एक बढ़त का प्रतिनिधित्व करता है में डेटा प्राप्त करने के लिए। फिर ग्राफ विश्लेषण के लिए networkx ऑब्जेक्ट में माइग्रेट करें।

बढ़त साझा करने दो नोड्स के लिए मापदंड में शामिल हैं:

  1. एक ही स्थान मान लिया जाये कि इसका मतलब है एक ही gps1 और gps2
  2. "उसी शुरुआत और समाप्ति समय के पास" यह थोड़ा अस्पष्ट है। इस उत्तर के प्रयोजनों के लिए मैंने इस मानदंड को "उसी 5-सेकंड अंतराल में प्रारंभ समय" पर घटा दिया है। यदि आप किनारों पर अतिरिक्त अस्थायी स्थितियां लागू करना चाहते हैं तो groupby दृष्टिकोण को विस्तारित करना बहुत कठिन नहीं होना चाहिए।

हम, timestamps के आधार पर डेटा हेरफेर करने के लिए datetimedtype को start और end परिवर्तित चाहते हैं के बाद से:

df.start = pd.to_datetime(df.start, unit="s") 
df.end = pd.to_datetime(df.end, unit="s") 

df.start.describe() 
count      35 
unique      11 
top  2004-01-05 00:00:13 
freq      8 
first  2004-01-05 00:00:01 
last  2004-01-05 00:00:26 
Name: start, dtype: object 

df.head() 
      ID    start     end gps1 gps2 
0 0022d9064bc 2004-01-05 00:00:01 2004-01-05 00:00:03 819251 440006 
1 00022d9064bc 2004-01-05 00:00:03 2004-01-05 00:00:10 819213 439954 
2 00904b4557d3 2004-01-05 00:00:03 2004-01-05 00:18:40 817526 439458 
3 00022de73863 2004-01-05 00:00:04 2004-01-05 01:16:50 817558 439525 
4 00904b14b494 2004-01-05 00:00:04 2004-01-05 00:30:25 817558 439525 

नमूना टिप्पणियों को एक दूसरे के कुछ ही सेकंड के भीतर हो, तो हम grouping frequency सेट करेंगे होने के लिए केवल कुछ सेकंड:

near = "5s" 

अब groupby स्थान और प्रारंभ समय पंख d जुड़े नोड्स:

edges = (df.groupby(["gps1", 
        "gps2", 
        pd.Grouper(key="start", 
           freq=near, 
           closed="right", 
           label="right")], 
        as_index=False) 
      .agg({"ID":','.join, 
       "start":"min", 
       "end":"max"}) 
      .reset_index() 
      .rename(columns={"index":"edge", 
          "start":"start_min", 
          "end":"end_max"}) 
     ) 

edges.ID = edges.ID.str.split(",") 

edges.head():

edge gps1 gps2             ID \ 
0  0 817526 439458          [00904b4557d3] 
1  1 817558 439525 [00022de73863, 00904b14b494, 00904b14b494, 009... 
2  2 817558 439525   [00022de73863, 00904b14b494, 00904b312d9e] 
3  3 817721 439564 [00022d176cf3, 000c30d8d2e8, 00904b243bc4, 009... 
4  4 817735 439757      [003065d2d8b6, 00904b0c7856] 

      start_min    end_max 
0 2004-01-05 00:00:03 2004-01-05 00:18:40 
1 2004-01-05 00:00:04 2004-01-05 01:16:50 
2 2004-01-05 00:00:25 2004-01-05 00:01:19 
3 2004-01-05 00:00:13 2004-01-05 00:02:42 
4 2004-01-05 00:00:17 2004-01-05 01:52:40 

प्रत्येक पंक्ति अब एक अनूठा बढ़त श्रेणी का प्रतिनिधित्व करता है। ID उस किनारे के सभी शेयरों में नोड्स की एक सूची है। इस सूची को नोड-जोड़े की नई संरचना में लाने के लिए थोड़ा मुश्किल है; मैंने कुछ पुराने फैशन वाले नेस्टेड फॉर-लूप्स का सहारा लिया है। संभवतः कुछ पांडस-फु है जो यहां दक्षता में सुधार कर सकते हैं:

नोट: सिंगलटन नोड के मामले में, मैंने अपनी जोड़ी में None मान असाइन किया है। यदि आप सिंगलेट्स को ट्रैक नहीं करना चाहते हैं, तो बस if not len(combos): ... तर्क को अनदेखा करें।

pairs = [] 
idx = 0 
for e in edges.edge.values: 
    nodes = edges.loc[edges.edge==e, "ID"].values[0] 
    attrs = edges.loc[edges.edge==e, ["gps1","gps2","start_min","end_max"]] 
    combos = list(combinations(nodes, 2)) 
    if not len(combos): 
     pair = [e, nodes[0], None] 
     pair.extend(attrs.values[0]) 
     pairs.append(pair) 
     idx += 1 
    else: 
     for combo in combos: 
      pair = [e, combo[0], combo[1]] 
      pair.extend(attrs.values[0]) 
      pairs.append(pair) 
      idx += 1 
cols = ["edge","nodeA","nodeB","gps1","gps2","start_min","end_max"] 
pairs_df = pd.DataFrame(pairs, columns=cols)  

pairs_df.head():

edge   nodeA   nodeB gps1 gps2   start_min \ 
0  0 00904b4557d3   None 817526 439458 2004-01-05 00:00:03 
1  1 00022de73863 00904b14b494 817558 439525 2004-01-05 00:00:04 
2  1 00022de73863 00904b14b494 817558 439525 2004-01-05 00:00:04 
3  1 00022de73863 00904b14b494 817558 439525 2004-01-05 00:00:04 
4  1 00904b14b494 00904b14b494 817558 439525 2004-01-05 00:00:04 

       end_max 
0 2004-01-05 00:18:40 
1 2004-01-05 01:16:50 
2 2004-01-05 01:16:50 
3 2004-01-05 01:16:50 
4 2004-01-05 01:16:50  

अब डेटा एक networkx वस्तु के लिए फिट हो सकते हैं:

import networkx as nx 

g = nx.from_pandas_dataframe(pairs_df, "nodeA", "nodeB", edge_attr=True) 

# access edge attributes by node pairing: 
test_A = "00022de73863" 
test_B = "00904b14b494" 
g[test_A][test_B]["start_min"] 
# output: 
Timestamp('2004-01-05 00:00:25') 

समुदाय का पता लगाने के लिए, वहाँ कई विकल्प हैं। networkx community algorithms पर विचार करें, साथ ही community मॉड्यूल पर विचार करें, जो मूल networkx कार्यक्षमता से बना है।

मैंने आपके प्रश्न को मुख्य रूप से नेटवर्क विश्लेषण के लिए उपयुक्त प्रारूप में अपने डेटा में हेरफेर करने के साथ चिंतित किया है। चूंकि यह उत्तर पहले से काफी लंबा है, मैं इसे समुदाय पहचान रणनीतियों का पीछा करने के लिए छोड़ दूंगा - मैंने यहां से जुड़े मॉड्यूल के साथ कई तरीकों का उपयोग किया जा सकता है।

+0

यह बहुत अच्छा है .. बहुत बहुत धन्यवाद .. हाँ यह है प्रक्रिया के लिए लंबा .. समाधान सही .. मुझे सीएसवी से पढ़ने और सीएसवी पर वापस लिखना है .. –

+0

हाँ यह बहुत कुछ करता है .. मुझे परीक्षण भी नहीं करना है .. क्या मैं आपसे अनुरोध कर सकता हूं कि आप सभी को मॉड्यूल को एक साथ पढ़ने और लिखने के मॉड्यूल के साथ एक साथ .. यह एक विनम्र अनुरोध है .. –

+0

एक संपादन करने के लिए खुश है, लेकिन मुझे यकीन नहीं है कि आपका क्या मतलब है। मैंने जो मॉड्यूल जोड़ा है वह 'networkx' था, इसके अलावा सिर्फ पांडस। मैंने 'networkx' के लिए 'आयात' कथन जोड़ा है। अगर आप कुछ और ढूंढ रहे हैं तो मुझे बताएं। अगर आपको यकीन नहीं है कि पांडों से डेटा कैसे पढ़ना/लिखना है, तो एक अलग प्रश्न खोलने पर विचार करें या बस [पांडस I/O दस्तावेज़] देखें (http://pandas.pydata.org/pandas-docs/stable/io.html) ... –

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