2016-06-28 45 views
9

Ho un telaio panda simile a questo:Ricerca di un posto elementi della matrice in una colonna telaio pandi (alias pd.series)

import pandas as pd 
import numpy as np 

data = {'Col1' : [4,5,6,7], 'Col2' : [10,20,30,40], 'Col3' : [100,50,-30,-50], 'Col4' : ['AAA', 'BBB', 'AAA', 'CCC']} 

df = pd.DataFrame(data=data, index = ['R1','R2','R3','R4']) 

    Col1 Col2 Col3 Col4 
R1  4 10 100 AAA 
R2  5 20 50 BBB 
R3  6 30 -30 AAA 
R4  7 40 -50 CCC 

Dato un array di obiettivi:

target_array = np.array(['AAA', 'CCC', 'EEE']) 

I vorrebbe trovare gli indici di elementi di cella in Col4 che compaiono anche nello target_array.

Ho cercato di trovare una risposta documentata ma sembra oltre le mie capacità ... Qualcuno ha qualche consiglio?

P.S. Per inciso, per questo caso particolare posso inserire un array di destinazione i cui elementi sono i nomi degli indici del frame dati array(['R1', 'R3', 'R5']). Sarebbe più facile in questo modo?

Edit 1:

Grazie mille per tutte le grandi risposte. Purtroppo posso sceglierne solo uno, ma tutti sembrano indicare @Divakar come il migliore. Ancora si dovrebbe guardare piRSquared e MaxU confronti di velocità per tutte le possibilità disponibili

risposta

10

È possibile utilizzare NumPy's in1d -

df.index[np.in1d(df['Col4'],target_array)] 

Spiegazione

1) Creare una maschera 1D corrispondente a ciascuna riga dirci se vi sia una corrispondenza tra col4's elemento ed ogni elemento in target_array:

mask = np.in1d(df['Col4'],target_array) 

2) Utilizzare la maschera per selezionare gli indici validi dal dataframe come output finale:

out = df.index[np.in1d(df['Col4'],target_array)] 
+0

Questo è più veloce! – piRSquared

+0

@piRSquared Beh, speravo tanto, essere una cosa di NumPy! ;) – Divakar

+0

Lo terrò sicuramente a mente. – piRSquared

9

Questo dovrebbe farlo:

df.loc[df.Col4.isin(target_array)].index 

EDIT:

ho corse tre opzioni: da risposte selezionate. Mine, Bruce Pucci, e Divakar

enter image description here

Divakars era più veloce da una grande quantità. Lo sceglierei.

+0

la ringrazio molto per il confronto, è molto ordinato.Solo una domanda: pensi che il tipo di dati (str) stia influenzando la velocità in modo diverso su ciascun metodo? – Delosari

+0

Cambia le cose marginalmente. Ma l'ordine rimane lo stesso. – piRSquared

+0

Questo è bello sapere. Grazie mille per la risposta ancora – Delosari

5
import pandas as pd 
import numpy as np 

data = {'Col1' : [4,5,6,7], 'Col2' : [10,20,30,40], 'Col3' : [100,50,-30,-50], 'Col4' : ['AAA', 'BBB', 'AAA', 'CCC']} 
target_array = np.array(['AAA', 'CCC', 'EEE']) 

df = pd.DataFrame(data=data, index = ['R1','R2','R3','R4']) 

df['in_col'] = df['Col4'].apply(lambda x: x in target_array) 

È questo quello che stavi cercando? Quindi puoi raggruppare la nuova colonna e interrogare gli elementi True.

+0

Grazie mille per avermi ricordato la mia lambda: sono piuttosto nuovo in Python e questo è uno strumento molto potente/flessibile – Delosari

4
df.index[df.Col4.isin(target_array)] 
+0

Grazie per la risposta ... è un approccio molto pulito dal momento che usa solo le funzioni panda – Delosari

7

Per ragioni di completezza Ho aggiunto due (.query() varianti) - i miei tempi contro 400K righe df:

In [63]: df.shape 
Out[63]: (400000, 4) 

In [64]: %timeit df.index[np.in1d(df['Col4'],target_array)] 
10 loops, best of 3: 35.1 ms per loop 

In [65]: %timeit df.index[df.Col4.isin(target_array)] 
10 loops, best of 3: 36.7 ms per loop 

In [66]: %timeit df.loc[df.Col4.isin(target_array)].index 
10 loops, best of 3: 47.8 ms per loop 

In [67]: %timeit df.query('@target_array.tolist() == Col4') 
10 loops, best of 3: 45.7 ms per loop 

In [68]: %timeit df.query('@target_array in Col4') 
10 loops, best of 3: 51.9 ms per loop 

Here is a similar comparison for (not in ...) and for different dtypes

+1

Grazie mille per le opzioni di query, è una scoperta molto bella – Delosari