2017-04-06 1 views
0

Ich habe ein Skript, das die Zeilen und Spalten Header einer Gruppe (REG_ID) betrachtet und die Werte summiert. Der Code läuft auf einer Matrix (kleine Untergruppe) wie folgt:Erstellen Sie interne Python-Schleife basierend auf Index und Gruppierungen für alle Kombinationen

Outputs

Mein Code läuft gut für die Berechnung der Summe der für alle IDs basierend auf Zeilen und Spalten auf jede interne Gruppe gehören (REG_ID). Zum Beispiel werden für alle Zeilen- und Spalten-IDs, die zu REG_ID gehören, 1 summiert, so dass die Gesamtströme zwischen Region 1 und Region 1 (interne Flüsse) berechnet werden und so weiter für jede Region. Ich möchte diesen Code durch Berechnen (Summieren) der Flüsse zwischen den Regionen zum Beispiel Region 1 zu Region 2, 3, 4, 5 .... Ich denke, ich muss eine andere Schleife innerhalb der bestehenden While-Schleife enthalten, würde aber schätze wirklich etwas Hilfe, um herauszufinden, wo es sein sollte und wie man es konstruiert. Mein Code, der auf der inneren Strömungs Summe zur Zeit läuft (1-1, 2-2, 3-3 usw.) ist wie folgt:

global index 
index = 1 
x = index 
while index < len(idgroups): 
    ward_list = idgroups[index] #select list of ward ids for each region from list of lists 
    df6 = mergedcsv.loc[ward_list] #select rows with values in the list 
    dfcols = mergedcsv.loc[ward_list, :] #select columns with values in list 
    ward_liststr = map(str, ward_list) #convert ward_list to strings so that they can be used to select columns, won't work as integers. 
    ward_listint = map(int, ward_list) 
    #dfrowscols = mergedcsv.loc[ward_list, ward_listint] 
    df7 = df6.loc[:, ward_liststr] 
    print df7 
    regflowsum = df7.values.sum() #sum all values in dataframe 
    intflow = [regflowsum] 
    print intflow 
    dfintflow = pd.DataFrame(intflow) 
    dfintflow.reset_index(level=0, inplace=True) 
    dfintflow.columns = ["RegID", "regflowsum"] 
    dfflows.set_value(index, 'RegID', index) 
    dfflows.set_value(index, 'RegID2', index) 
    dfflows.set_value(index, 'regflow', regflowsum) 
    mergedcsv.set_value(ward_list, 'TotRegFlows', regflowsum) 
    index += 1 #increment index number 
print dfflows 
new_df = pd.merge(pairlist, dfflows, how='left', left_on=['origID','destID'], right_on = ['RegID', 'RegID2']) 
print new_df #useful for checking dataframe merges 
regionflows = r"C:\Temp\AllNI\regionflows.csv" 
header = ["WardID","LABEL","REG_ID","Total","TotRegFlows"] 
mergedcsv.to_csv(regionflows, columns = header, index=False) 
regregflows = r"C:\Temp\AllNI\reg_regflows.csv" 
headerreg = ["REG_ID_ORIG", "REG_ID_DEST", "FLOW"] 

pairlistCSV = r"C:\Temp\AllNI\pairlist_regions.csv" 
new_df.to_csv(pairlistCSV) 

Die Ausgabe ist wie folgt:

idgroups Datenrahmen: (siehe Abbildung 1 - zweiten Teil des Bildes 1)

DF7 und intflows für jede Region Reg_ID: (dritten Teil des Bildes 1 - auf dem rechten Seite)

ddflows Datenrahmen: (vierten Teil des Bildes 2)

und die endgültige Ausgabe ist new_df: (fünfter Teil von Bild 2)

Ich möchte die Summen für alle möglichen Kombinationen von Bewegungen zwischen den Regionen nicht nur intern zu füllen.

Ich denke, ich muss eine weitere Schleife in die While-Schleife hinzufügen. So fügen Sie möglicherweise eine enumerate Funktion wie:

while index < len(idgroups): 
    #add line(s) to calculate flows between regions 
    for index, item in enumerate(idgroups): 
     ward_list = idgroups[index] 
     print ward_list 
     df6 = mergedcsv.loc[ward_list] #select rows with values in the list 
     dfcols = mergedcsv.loc[ward_list, :] #select columns with values in list 
     ward_liststr = map(str, ward_list) #convert ward_list to strings so that they can be used to select columns, won't work as integers. 
     ward_listint = map(int, ward_list) 
     #dfrowscols = mergedcsv.loc[ward_list, ward_listint] 
     df7 = df6.loc[:, ward_liststr] 
     print df7 
     regflowsum = df7.values.sum() #sum all values in dataframe 
     intflow = [regflowsum] 
     print intflow 
     dfintflow = pd.DataFrame(intflow) 
     dfintflow.reset_index(level=0, inplace=True) 
     dfintflow.columns = ["RegID", "regflowsum"] 
     dfflows.set_value(index, 'RegID', index) 
     dfflows.set_value(index, 'RegID2', index) 
     dfflows.set_value(index, 'regflow', regflowsum) 
     mergedcsv.set_value(ward_list, 'TotRegFlows', regflowsum) 
     index += 1 #increment index number 

Ich bin nicht sicher, wie das Element zu integrieren, so kämpfen, um den Code für alle Kombinationen zu erweitern. Jeder Rat geschätzt.

aktualisieren basierend auf Flüsse funktionieren:

w=pysal.rook_from_shapefile("C:/Temp/AllNI/NIW01_sort.shp",idVariable='LABEL') 
Simil = pysal.open("C:/Temp/AllNI/simNI.csv") 
Similarity = np.array(Simil) 
db = pysal.open('C:\Temp\SQLite\MatrixCSV2.csv', 'r') 
dbf = pysal.open(r'C:\Temp\AllNI\NIW01_sortC.dbf', 'r') 
ids = np.array((dbf.by_col['LABEL'])) 
commuters = np.array((dbf.by_col['Total'],dbf.by_col['IDNO'])) 
commutersint = commuters.astype(int) 
comm = commutersint[0] 
floor = int(MIN_COM_CT + 100) 
solution = pysal.region.Maxp(w=w,z=Similarity,floor=floor,floor_variable=comm) 
regions = solution.regions 
#print regions 
writecsv = r"C:\Temp\AllNI\reg_output.csv" 
csv = open(writecsv,'w') 
csv.write('"LABEL","REG_ID"\n') 
for i in range(len(regions)): 
     for lines in regions[i]: 
      csv.write('"' + lines + '","' + str(i+1) + '"\n') 
csv.close() 
flows = r"C:\Temp\SQLite\MatrixCSV2.csv" 
regs = r"C:\Temp\AllNI\reg_output.csv" 
wardflows = pd.read_csv(flows) 
regoutput = pd.read_csv(regs) 
merged = pd.merge(wardflows, regoutput) 
#duplicate REG_ID column as the index to be used later 
merged['REG_ID2'] = merged['REG_ID'] 
merged.to_csv("C:\Temp\AllNI\merged.csv", index=False) 
mergedcsv = pd.read_csv("C:\Temp\AllNI\merged.csv",index_col='WardID_1') #index this dataframe using the WardID_1 column 
flabelList = pd.read_csv("C:\Temp\AllNI\merged.csv", usecols = ["WardID", "REG_ID"]) #create list of all FLabel values 

reg_id = "REG_ID" 
ward_flows = "RegIntFlows" 
flds = [reg_id, ward_flows] #create list of fields to be use in search 

dict_ref = {} # create a dictionary with for each REG_ID a list of corresponding FLABEL fields 


#group the dataframe by the REG_ID column 
idgroups = flabelList.groupby('REG_ID')['WardID'].apply(lambda x: x.tolist()) 
print idgroups 

idgrp_df = pd.DataFrame(idgroups) 

csvcols = mergedcsv.columns 

#create a list of column names to pass as an index to select columns 
columnlist = list(mergedcsv.columns.values) 

mergedcsvgroup = mergedcsv.groupby('REG_ID').sum() 
mergedcsvgroup.describe() 
idList = idgroups[2] 
df4 = pd.DataFrame() 
df5 = pd.DataFrame() 
col_ids = idList #ward id no 

regiddf = idgroups.index.get_values() 
print regiddf 
#total number of region ids 
#print regiddf 
#create pairlist combinations from region ids 
#combinations with replacement allows for repeated items 
#pairs = list(itertools.combinations_with_replacement(regiddf, 2)) 
pairs = list(itertools.product(regiddf, repeat=2)) 
#print len(pairs) 

#create a new dataframe with pairlists and summed data 
pairlist = pd.DataFrame(pairs,columns=['origID','destID']) 
print pairlist.tail() 
header_pairlist = ["origID","destID","flow"] 
header_intflow = ["RegID", "RegID2", "regflow"] 
dfflows = pd.DataFrame(columns=header_intflow) 

print mergedcsv.index 
print mergedcsv.dtypes 
#mergedcsv = mergedcsv.select_dtypes(include=['int64']) 
#print mergedcsv.columns 
#mergedcsv.rename(columns = lambda x: int(x), inplace=True) 

def flows(): 
    pass 

#def flows(mergedcsv, region_a, region_b): 
def flows(mergedcsv, ward_lista, ward_listb): 
    """Return the sum of all the cells in the row/column intersections 
    of ward_lista and ward_listb.""" 

    mergedcsv = mergedcsv.loc[:, mergedcsv.dtypes == 'int64'] 
    regionflows = mergedcsv.loc[ward_lista, ward_listb] 
    regionflowsum = regionflows.values.sum() 


    #grid = [ax, bx, regflowsuma, regflowsumb] 
    gridoutput = [ax, bx, regionflowsum] 
    print gridoutput 

    return regflowsuma 
    return regflowsumb 

#print mergedcsv.index 

#mergedcsv.columns = mergedcsv.columns.str.strip() 

for ax, group_a in enumerate(idgroups): 
    ward_lista = map(int, group_a) 
    print ward_lista 


    for bx, group_b in enumerate(idgroups[ax:], start=ax): 
     ward_listb = map(int, group_b) 
     #print ward_listb 

     flow_ab = flows(mergedcsv, ward_lista, ward_listb) 
      #flow_ab = flows(mergedcsv, group_a, group_b) 

Dies KeyError Ergebnisse: 'Keiner von [[189, 197, 198, 201]] sind in den [Spalten]

ich versucht habe, Mit ward_lista = map (str, group_a) und map (int, group_a) werden auch Objekte aufgelistet, die nicht in dataframe.loc gefunden wurden. Die Spalten sind gemischte Datentypen, aber alle Spalten, die die zu schneidenden Beschriftungen enthalten, sind vom Typ int64. Ich habe viele Lösungen um die Datentypen versucht, aber ohne Erfolg. Irgendwelche Vorschläge?

Antwort

0

Ich kann nicht mit den Berechnungen, die Sie tun, sprechen, aber es scheint, als ob Sie nur Kombinationen von Gruppen arrangieren möchten. Die Frage ist, ob sie gerichtet oder ungerichtet sind - dh, müssen Sie Flüsse (A, B) und Flüsse (B, A) oder nur einen berechnen?

Wenn nur eine, man könnte dies tun:

for i,ward_list in enumerate(idgroups): 
    for j,ward_list2 in enumerate(idgroups[i:],start=i): 

Das würde ich iterieren, j Paare wie:

0,0 0,1 0,2 ... 0,n 
1,1 1,2 ... 1,n 
2,2 ... 2,n 

die im ungerichteten Fall dienen würde.

Wenn Sie beiden Ströme berechnen müssen (A, B) und fließt (B, A), dann können Sie einfach Ihren Code in eine Funktion Push flows genannt und mit umgekehrtem args nennen, wie dargestellt.

;-)

aktualisieren

Lassen Sie uns eine Funktion flows genannt definieren:

def flows(): 
    pass 

Nun, was sind die Parameter?

Nun, wenn Sie Ihren Code betrachten, erhält er Daten von einem DataFrame. Und Sie wollen zwei verschiedene Stationen, also fangen wir mit denen an. Das Ergebnis scheint eine Summe des resultierenden Rasters zu sein.

def flows(df, ward_a, ward_b): 
    """Return the sum of all the cells in the row/column intersections 
    of ward_a and ward_b.""" 

    return 0 

Jetzt werde ich Zeilen Code kopieren:

ward_list = idgroups[index] 
    print ward_list 
    df6 = mergedcsv.loc[ward_list] #select rows with values in the list 
    dfcols = mergedcsv.loc[ward_list, :] #select columns with values in list 
    ward_liststr = map(str, ward_list) #convert ward_list to strings so that they can be used to select columns, won't work as integers. 
    ward_listint = map(int, ward_list) 
    #dfrowscols = mergedcsv.loc[ward_list, ward_listint] 
    df7 = df6.loc[:, ward_liststr] 
    print df7 
    regflowsum = df7.values.sum() #sum all values in dataframe 
    intflow = [regflowsum] 
    print intflow 

Ich denke, das den größten Teil der flow Funktion ist hier richtig. Lass uns nachsehen.

  1. Die ward_list wird offensichtlich entweder die ward_a oder ward_b Parameter.

  2. Ich bin nicht sicher, was df6 ist, weil Sie es in df7 Art neu berechnen. Das muss geklärt werden.

  3. regflowsum ist unsere gewünschte Leistung, denke ich.

Umschreiben diese in die Funktion:

def flows(df, ward_a, ward_b): 
    """Return the sum of all the cells in the row/column intersections 
    of ward_a and ward_b.""" 

    print "Computing flows from:" 
    print " ", ward_a 
    print "" 
    print "flows into:" 
    print " ", ward_b 

    # Filter rows by ward_a, cols by ward_b: 
    grid = df.loc[ward_a, ward_b] 

    print "Grid:" 
    print grid 

    flowsum = grid.values.sum() 

    print "Flows:", flowsum 

    return flowsum 

Jetzt habe ich angenommen, dass die ward_a und ward_b Werte sind bereits im richtigen Format. Also müssen wir str -ify sie oder was auch immer außerhalb der Funktion. Lassen Sie uns das tun:

for ax, group_a in enumerate(idgroups): 
    ward_a = map(str, group_a) 

    for bx, group_b in enumerate(idgroups[ax:], start=ax): 
     ward_b = map(str, group_b) 

     flow_ab = flows(mergedcsv, ward_a, ward_b) 

     if ax != bx: 
      flow_ba = flows(mergedcsv, ward_b, ward_a) 
     else: 
      flow_ba = flow_ab 

     # Now what? 

An diesem Punkt haben Sie zwei Zahlen. Sie sind gleich, wenn die Stationen gleich sind (interner Fluss?). An dieser Stelle hört der ursprüngliche Code auf, hilfreich zu sein, da er nur interne Flüsse und nicht A-> B-Flüsse behandelt, also weiß ich nicht, was zu tun ist. Aber die Werte sind in den Variablen, also ...

+0

Austin, danke. Dies ist eine große Hilfe. Ich möchte die Flüsse berechnen, die von A nach B und von B nach A gerichtet sind. Ich war nicht auf die Flows-Funktion gestoßen, also werde ich das untersuchen. –

+0

Es gibt keine Flows-Funktion. Sie müssen es mit Ihren Berechnungen schreiben. –

+0

Austin, Ihr Vorschlag war sehr hilfreich. Das Hinzufügen einer Flow-Funktion ist sehr logisch.Ich habe den Code basierend auf Ihrem Rat aktualisiert. Ich habe anscheinend einen Datentypfehler oder einen Indexierungsfehler. Ich habe versucht, viele Versuche zu lösen, einschließlich der Zuordnung zu int und Auswahl aller Spalten des Typs int64, aber immer noch Fehler. Können Sie einen offensichtlichen Fehler erkennen? Vielen Dank für Ihren Hinweis –

Verwandte Themen