2016-06-28 14 views
9

mam ramkę pandas podobny do tego:Znalezienie elementy tablicy położenie w kolumnie ramki pandy (aka 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 

Biorąc pod uwagę macierz celów:

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

I chciałby znaleźć indeksy elementów komórki w Col4, które również pojawiają się w target_array.

Próbowałem znaleźć udokumentowaną odpowiedź, ale wydaje mi się to poza moimi umiejętnościami ... Czy ktoś ma jakieś rady?

P.S. Nawiasem mówiąc, w tym konkretnym przypadku mogę wprowadzić docelową tablicę, której elementami są indeksy ramek danych o nazwach array(['R1', 'R3', 'R5']). Czy byłoby łatwiej w ten sposób?

Edit 1:

Dziękuję bardzo za wszystkie wielkie odpowiedzi. Niestety mogę wybrać tylko jeden, ale wszyscy wydają się wskazywać @Divakar jako najlepszy. Nadal należy spojrzeć na piRSquared i MaxU porównań prędkości dla wszystkich możliwości dostępnych

Odpowiedz

10

Można użyć NumPy's in1d -

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

Wyjaśnienie

1) Tworzenie 1D maskę odpowiadającą każdym wierszu mówi nam, czy istnieje zgodność między col4's elementu i każdego elementu w target_array:

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

2) Za pomocą maski do wyboru poprawnych indeksów z dataframe jako finalnego:

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

To jest szybsze! – piRSquared

+0

@piRSquared Cóż, miałem taką nadzieję, będąc rzeczą NumPy! ;) – Divakar

+0

Na pewno będę o tym pamiętać. – piRSquared

9

Powinien to zrobić:

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

EDIT:

wpadłem trzy opcje: z wybranych odpowiedzi. Kopalnia, Bruce Pucci i Divakar

enter image description here

Divakars był szybszy przez dużą kwotę. Wybrałbym jego.

+0

Dziękuję bardzo za porównanie, to jest bardzo miłe.Tylko jedno pytanie: Czy uważasz, że typ danych (str) wpływa inaczej na szybkość każdej metody? – Delosari

+0

Zmienia to nieznacznie. Ale kolejność pozostaje taka sama. – piRSquared

+0

Dobrze o tym wiedzieć. Dziękuję bardzo za odpowiedź ponownie – 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) 

Czy tego właśnie szukasz? Następnie możesz pogrupować nową kolumnę i zapytać o elementy True.

+0

Bardzo dziękuję za przypomnienie mojej zasady lambda: jestem raczej nowym użytkownikiem Pythona i jest to bardzo potężne/elastyczne narzędzie – Delosari

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

Dziękuję za odpowiedź ... to bardzo miłe podejście ponieważ używa tylko funkcji pandy – Delosari

7

Dla kompletności dodałem dwie (.query() warianty) - moje czasy przed 400k wierszy 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

Dziękuję bardzo za opcje zapytania, to bardzo miłe odkrycie – Delosari

Powiązane problemy