2017-03-20 2 views
0

大きなパンダのデータフレームで多数の単語を検索していますが、パフォーマンスに問題があります。 pandasデータフレームの列の文字列をバイナリ検索する方法はありますか?パンダのデータフレームでのバイナリ検索?

今の私のコードは次のようである:

names = pd.DataFrame(data=['one', 'two', 'three', 'four'], index=range(0, 4), columns=['Name']) 
sentence = 'There are two trees in the street.' 

for word in word_tokenize(sentence): 
    # Search for each word in all the names 
    new_names = names[names['Name'].str.startswith(word)] 
    # then do some operations on the names 

しかし、私はnames[names['Name'].str.startswith(word)]のためのより良いパフォーマンスを必要とし、私は「名前」列にバイナリ検索への道を見つけなければならないと思いました。

+0

正確にあなたが試してみましたか?あなたはもっと具体的な方法を与える必要があります。試したいくつかのコードをサンプルDataFrameに提供することは長い道のりになります。 –

+0

@TedPetrouありがとう!私は少し質問を変更しました。 – AmirAhmad

+0

答えを提供するのに十分な詳細がまだありません。 'iterrows'の下で何が起こっているのですか?通常、iterrowsの使用は避けてください。より多くの情報を持つサンプルデータフレームは、長い道のりを行くでしょう。 –

答えて

1

このアプローチには少なくとも2つの問題があります。最初に、names['Name'].str.startswith(word)がキャッシュされる可能性がありますが、すべての単語について計算されます。次に、startswith()は単語 "the"の "There"と一致します。コードに翻訳し、この方法を変更することができます。

# calculate startword only once. 
startword = names.apply(lambda row: row['Name'].split(" ", 1)[0]) 

for word in word_tokenize(sentence): 
    # also, match by the full word only 
    new_names = names[startword == word] 

startwordがインデックスした場合、それがさらに高速になります

names.index = startword 
for word in word_tokenize(sentence): 
    # also, match by the full word only 
    new_names = names.loc[word] 
+0

ありがとう!この.loc []は、そのスタートワードを持つ複数の行があるときにデータフレームを返しますが、行が1つしかない場合は、別のデータ型を返します。そのための解決法はありますか? – AmirAhmad

+0

@AmirAhmadは 'names.loc [word]'の代わりに 'names.loc [[word]]'を使うだけです – Marat

関連する問題