2016-09-16 4 views
1

Ich erstellte einen DataFrame neighbours mit sim_measure_i, die auch ein DataFrame ist.Verarbeiten einer Liste in einer Dataframe-Spalte

neighbours= sim_measure_i.apply(lambda s: s.nlargest(k).index.tolist(), axis =1) 

neighbours sieht wie folgt aus:

1500      [0, 1, 2, 3, 4] 
1501      [0, 1, 2, 3, 4] 
1502      [0, 1, 2, 3, 4] 
1503  [7230, 12951, 13783, 8000, 18077] 
1504      [1, 3, 6, 27, 47] 

Die zweite Spalte hat hier Listen - ich über diese Datenrahmen und die Arbeit an der Liste zu durchlaufen wollen, so dass ich jedes Element in der Liste lesen kann - sagen 7230 und suchen Sie eine Punktzahl für 7230 in einem anderen DataFrameI haben, die enthält (ID, Score).

würde ich dann gerne eine Spalte zu diesem Datenrahmen hinzuzufügen, so dass es wie

test_case_id    nbr_list    scores    
1500      [0, 1, 2, 3, 4]  [+1, -1, -1, +1, -1] 
1501      [0, 1, 2, 3, 4]  [+1, +1, +1, -1, -1] 
1502      [0, 1, 2, 3, 4]  [+1, +1, +1, -1, -1] 
1503  [7230, 12951, 13783, 8000, 18077]  [+1, +1, +1, -1, -1] 
1504      [1, 3, 6, 27, 47]  [+1, +1, +1, -1, -1] 

Bearbeiten sieht: ich geschrieben habe, ein Verfahren get_scores()

def get_scores(list_of_neighbours): 
    score_matrix = [] 
    for x, val in enumerate(list_of_neighbours): 
     score_matrix.append(df.iloc[val].score) 
    return score_matrix 

Wenn ich versuche, lambda zu verwenden, um auf jeder nbr_list ich diesen Fehler:

TypeError: ("cannot do positional indexing on <class 'pandas.indexes.numeric.Int64Index'> with these indexers [0] of <type 'str'>", u'occurred at index 1500') 

Der Code verursacht dieses Problem:

def nearest_neighbours(similarity_matrix, k): 
    neighbours = pd.DataFrame(similarity_matrix.apply(lambda s: s.nlargest(k).index.tolist(), axis =1)) 
    neighbours = neighbours.rename(columns={0 : 'nbr_list'}) 

    nbr_scores = neighbours.apply(lambda l: get_scores(l.nbr_list), axis=1) 

    print neighbours 

Antwort

1

Sie können eine verschachtelte Schleife versuchen:

for i in range(neighbours.shape[0]): #iterate over each row 
    for j in range(len(neighbours['neighbours_lists'].iloc[i])): #iterate over each element of the list 
     a = neighbours['neighbours_lists'].iloc[i][j] #access the element of the list index j in cell location of row i 

wo i ist die äußere Schleifenvariable, die iteriert über jede Zeile und j die innere Schleifenvariable ist, die sich über iteriert die Länge der Liste innerhalb jeder Zelle.

1

Original Data Rahmen:

In [68]: df 
Out[68]: 
    test_case_id     neighbours_lists 
0   1500     [0, 1, 2, 3, 4] 
1   1501     [0, 1, 2, 3, 4] 
2   1502     [0, 1, 2, 3, 4] 
3   1503 [7230, 12951, 13783, 8000, 18077] 
4   1504     [1, 3, 6, 27, 47] 

Benutzerdefinierte Funktion, die ID und die Liste und hat einige Berechnung nimmt Punktzahl zu bewerten:

In [69]: def g(_id, nbs): 
    ...:  return ['-1' if (_id + 1) % (nb + 1) else '+1' for nb in nbs] 
    ...: 

Apply benutzerdefinierte Funktion auf alle Zeilen von Originaldatenrahmen:

In [70]: scores = df.apply(lambda x: g(x.test_case_id, x.neighbours_lists), axis=1) 

Convert die Punktzahl-Serie t o ein Datenrahmen und concat es mit dem ursprünglichen Datenrahmen:

In [71]: df = pd.concat([df, scores.to_frame(name='scores')], 1) 

In [72]: df 
Out[72]: 
    test_case_id     neighbours_lists    scores 
0   1500     [0, 1, 2, 3, 4] [+1, -1, -1, -1, -1] 
1   1501     [0, 1, 2, 3, 4] [+1, +1, -1, -1, -1] 
2   1502     [0, 1, 2, 3, 4] [+1, -1, +1, -1, -1] 
3   1503 [7230, 12951, 13783, 8000, 18077] [-1, -1, -1, -1, -1] 
4   1504     [1, 3, 6, 27, 47] [-1, -1, +1, -1, -1] 
+0

Thank you! Dies funktionierte mit leichten Modifikationen für meinen Fall. – boltthrower

1

Sagen Sie bitte mit neighbors suchen, wie diese zu starten.

In [87]: neighbors = pd.DataFrame({'neighbors_list': [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]}) 

In [88]: neighbors 
Out[88]: 
    neighbors_list 
0 [0, 1, 2, 3, 4] 
1 [0, 1, 2, 3, 4] 

Sie nicht genau angeben, wie die anderen Datenrahmen (die id-Score Paare aussehen enthalten), ist so hier eine Annäherung.

In [89]: id_score = pd.DataFrame({'id': [0, 1, 2, 3, 4], 'score': [1, -1, -1, 1, -1]}) 

In [90]: id_score 
Out[90]: 
    id score 
0 0  1 
1 1  -1 
2 2  -1 
3 3  1 
4 4  -1 

Sie können dies in ein Wörterbuch konvertieren:

In [91]: d = id_score.set_index('id')['score'].to_dict() 

Und dann apply:

In [92]: neighbors.neighbors_list.apply(lambda l: [d[e] for e in l]) 
Out[92]: 
0 [1, -1, -1, 1, -1] 
1 [1, -1, -1, 1, -1] 
Name: neighbors_list, dtype: object 
+0

Danke! Ich konnte es ohne ein Diktat machen, aber ich habe eine andere Methode durch deine Antwort gelernt. – boltthrower