2016-10-04 3 views
1

Ich habe Dataframe und ich versuche, nur Zeichenfolge zu erhalten, wo einige Spalte einige Zeichenfolgen enthalten.Pandas: Verbessern Algorithmus mit Finde Teilzeichenfolge in Spalte

Ich benutze:

df_res = pd.DataFrame() 
for i in substr: 
    res = df[df['event_address'].str.contains(i)] 

df wie folgt aussieht:

member_id,event_address,event_time,event_duration 
g1497o1ofm5a1963,fotki.yandex.ru/users/atanusha/albums,2015-05-01 00:00:05,8 
g1497o1ofm5a1963,9829192.ru/apple-iphone.html,2015-05-01 00:00:15,2 
g1497o1ofm5a1963,fotki.yandex.ru/users/atanusha/album/165150?&p=3,2015-05-01 00:00:17,2 
g1497o1ofm5a1963,fotki.yandex.ru/tags/%D0%B1%D0%BE%D1%81%D0%B8%D0%BA%D0%BE%D0%BC?text=%D0%B1%D0%BE%D1%81%D0%B8%D0%BA%D0%BE%D0%BC&search_author=utpaladev&&p=2,2015-05-01 00:01:31,10 
g1497o1ofm5a1963,3gmaster.net,2015-05-01 00:01:41,6 
g1497o1ofm5a1963,fotki.yandex.ru/search.xml?text=%D0%B1%D0%BE%D1%81%D0%B8%D0%BA%D0%BE%D0%BC&&p=2,2015-05-01 00:02:01,6 
g1497o1ofm5a1963,fotki.yandex.ru/search.xml?text=%D0%B1%D0%BE%D1%81%D0%B8%D0%BA%D0%BE%D0%BC&search_author=Sunny-Fanny&,2015-05-01 00:02:31,2 
g1497o1ofm5a1963,fotki.9829192.ru/apple-iphone.html,2015-05-01 00:03:25,6 

und substr ist:

123.ru/gadgets/communicators 
320-8080.ru/mobilephones 
3gmaster.net 
3-q.ru/products/smartfony/s 
9829192.ru/apple-iphone.html 
9829192.ru/index.php?cat=1 
acer.com/ac/ru/ru/content/group/smartphones 
aj.ru 

ich wünschenswertes Ergebnis mit diesem Code erhalten, aber es ist loo lang. Ich versuche auch, Spalte zu verwenden (substr es ist ein substr = urls.url.values.tolist()) und ich versuche

res = df[df['event_address'].str.contains(urls.url)] 

aber es gibt:

TypeError: 'Series' objects are mutable, thus they cannot be hashed

Ist es eine Möglichkeit, es schneller oder vielleicht zu machen, ich bin falsch ?

+0

Welcher Typ ist 'substr'? Ist das eine Liste von Zeichenfolgen? – albert

Antwort

1

Ich glaube, Sie join von | zu str.contains hinzufügen müssen, wenn schnellere Lösung benötigen:

res = df[df['event_address'].str.contains('|'.join(urls.url))] 
print (res) 
      member_id      event_address   event_time \ 
1 g1497o1ofm5a1963  9829192.ru/apple-iphone.html 2015-05-01 00:00:15 
4 g1497o1ofm5a1963      3gmaster.net 2015-05-01 00:01:41 
7 g1497o1ofm5a1963 fotki.9829192.ru/apple-iphone.html 2015-05-01 00:03:25 

    event_duration 
1    2 
4    6 
7    6 

Eine weitere list comprehension Lösung:

res = df[df['event_address'].apply(lambda x: any([n in x for n in urls.url.tolist()]))] 
print (res) 
      member_id      event_address   event_time \ 
1 g1497o1ofm5a1963  9829192.ru/apple-iphone.html 2015-05-01 00:00:15 
4 g1497o1ofm5a1963      3gmaster.net 2015-05-01 00:01:41 
7 g1497o1ofm5a1963 fotki.9829192.ru/apple-iphone.html 2015-05-01 00:03:25 

    event_duration 
1    2 
4    6 
7    6 

Timings:

#[8000 rows x 4 columns] 
df = pd.concat([df]*1000).reset_index(drop=True) 

In [68]: %timeit (df[df['event_address'].str.contains('|'.join(urls.url))]) 
100 loops, best of 3: 12 ms per loop 

In [69]: %timeit (df.ix[df.event_address.map(check_exists)]) 
10 loops, best of 3: 155 ms per loop 

In [70]: %timeit (df.ix[df.event_address.map(lambda x: any([True for i in urls.url.tolist() if i in x]))]) 
10 loops, best of 3: 163 ms per loop 

In [71]: %timeit (df[df['event_address'].apply(lambda x: any([n in x for n in urls.url.tolist()]))]) 
10 loops, best of 3: 174 ms per loop 
+0

Ich versuchte 'df ['event_address']. Str.contains ('|' .join (urls.url))' weil ich 'regex = True' hinzufügen muss, aber es gibt mir' sre_constants.error: multiple repeat' zurück –

2

wie folgt tun:

def check_exists(x): 
    for i in substr: 
     if i in x: 
      return True 
    return False 

df2 = df.ix[df.event_address.map(check_exists)] 

oder, wenn Sie es in einer Zeile schreiben:

df.ix[df.event_address.map(lambda x: any([True for i in substr if i in x]))] 

Verwandte Themen