2016-10-11 3 views
4

私はpeopleというデータフレームを持っています。このDataFrameの列の1つはplace_idです。私はまた、列の1つがplace_idであり、もう1つがweatherである場所のDataFrameを持っています。すべての人にとって、私は対応する天気を見つけようとしています。重要なことに、多くの人が同じplace_idを持っています。パンダスロー。 DataFrameで最初に発生したい

現在、私のセットアップはこれです:

def place_id_to_weather(pid): 
    return place_df[place_df['place_id'] == pid]['weather'].item() 

person_df['weather'] = person_df['place_id'].map(place_id_to_weather)` 

しかし、これはuntenably遅いです。私はこれをスピードアップしたいと思います。私はこのような高速化を達成できることを疑う:その列全体のためにplace_id == pidの検索を行い、シリーズを返しplace_df[...].item()を返し、その後、そのシリーズの最初の項目をつかむの代わりに

を、私は本当にただしたいです最初の一致がplace_df['place_id']==pidの後にplace_dfで検索を縮小します。その後、私はそれ以上検索する必要はありません。最初のオカレンスのみに検索を限定するにはどうすればよいですか?

ここでスピードアップを達成するために使用できる他の方法はありますか?結合型のメソッドのいくつかの種類ですか?

答えて

2

私は(それは多分on='place_id'が必要であり、データに依存)だけ共通の列place_idとの両方DataFramesweatherがある場合、あなたはパラメータonを省略することができ、あなたがmergedrop_duplicatesが必要だと思う:

df1 = place_df.drop_duplicates(['place_id']) 
print (df1) 

print (pd.merge(person_df, df1)) 

サンプルデータ:

person_df = pd.DataFrame({'place_id':['s','d','f','s','d','f'], 
          'A':[4,5,6,7,8,9]}) 
print (person_df) 
    A place_id 
0 4  s 
1 5  d 
2 6  f 
3 7  s 
4 8  d 
5 9  f 

place_df = pd.DataFrame({'place_id':['s','d','f', 's','d','f'], 
         'weather':['y','e','r', 'h','u','i']}) 
print (place_df) 
    place_id weather 
0  s  y 
1  d  e 
2  f  r 
3  s  h 
4  d  u 
5  f  i 
def place_id_to_weather(pid): 
    #for first occurence add iloc[0] 
    return place_df[place_df['place_id'] == pid]['weather'].iloc[0] 

person_df['weather'] = person_df['place_id'].map(place_id_to_weather) 
print (person_df) 
    A place_id weather 
0 4  s  y 
1 5  d  e 
2 6  f  r 
3 7  s  y 
4 8  d  e 
5 9  f  r 

#keep='first' is by default, so can be omit 
print (place_df.drop_duplicates(['place_id'])) 
    place_id weather 
0  s  y 
1  d  e 
2  f  r 

print (pd.merge(person_df, place_df.drop_duplicates(['place_id']))) 
    A place_id weather 
0 4  s  y 
1 7  s  y 
2 5  d  e 
3 8  d  e 
4 6  f  r 
5 9  f  r 
0

あなたは、操作を行うにmergeを使用することができます:あなたは同じ場所にはいくつかの天候を持っている場合は

people = pd.DataFrame([['bob', 1], ['alice', 2], ['john', 3], ['paul', 2]], columns=['name', 'place']) 

# name place 
#0 bob  1 
#1 alice  2 
#2 john  3 
#3 paul  2 

weather = pd.DataFrame([[1, 'sun'], [2, 'rain'], [3, 'snow'], [1, 'rain']], columns=['place', 'weather']) 

# place weather 
#0  1  sun 
#1  2 rain 
#2  3 snow 
#3  1 rain 

pd.merge(people, weather, on='place') 

# name place weather 
#0 bob  1  sun 
#1 bob  1 rain 
#2 alice  2 rain 
#3 paul  2 rain 
#4 john  3 snow 

を、あなたは、あなたが次の結果を持って、drop_duplicatesを使用することもできます。

pd.merge(people, weather, on='place').drop_duplicates(subset=['name', 'place']) 

# name place weather 
#0 bob  1  sun 
#2 alice  2 rain 
#3 paul  2 rain 
#4 john  3 snow 
1

マップ機能は、データフレーム全体を呼び出して一部の機能リピートを実行することを避けるための最も簡単な方法ですatedly。これはあなたがあなたの関数でやり遂げたことです。つまり、データフレーム全体を呼び出すことですが、それはうまくはできませんが、繰り返しはうまくいきません。コードを微調整するだけで、処理速度が大幅に向上し、place_dfデータフレームを1回呼び出すことができます。

person_df['weather'] = person_df['place_id'].map(dict(zip(place_df.place_id, place_df.weather))) 
関連する問題