2016-09-28 8 views
0

内のリンクを収集し、私はタイプは、効率的にデータフレーム

個人が場所と食品間のリンクを作成している
individual, location, food 
     1   A  a 
     1   A  b 
     1   B  a 
     1   A  c 
     2   C  a 
     2   C  b 

のデータフレームを持っていると言います。私は個人的にすべてのリンクを収集したいと思います。それは個人が場所ABで観察し、(最終的に)aで食品、b、およびcを持っていた場合、私はお互いに対してすべてこれらの場所や食品の種類をリンクしたい、次のとおりです。

location food 
      A  a 
      A  b 
      A  c 
      B  a 
      B  b 
      B  c 
      C  a 
      C  b 

1つ - 非常に非効率的です - その方法は

import itertools 
def foo(group): 
    list1 = group.location.unique() 
    list2 = group.food.unique() 
    return pd.DataFrame(data=list(itertools.product(list1, list2)), columns=['location', 'food']) 
df.groupby(df.individual).apply(foo) 

これを行うには良い方法はありますか?

答えて

2

効率を高めるには、numpyのmeshgridを使用します。

import itertools 
import numpy as np 
def foo(group): 
    list1 = group.location.unique() 
    list2 = group.food.unique() 
    return pd.DataFrame(data=list(itertools.product(list1, list2)), columns=['location', 'food']) 

def bar(group): 
    list1 = group.location.unique() 
    list2 = group.food.unique() 
    product = np.meshgrid(list1, list2) 
    # reversing the order is necessary to get the same output as foo 
    list3 = np.dstack([product[1], product[0]]).reshape(-1, 2) 
    return pd.DataFrame(data=list3, columns=['location', 'food']) 

は、私のマシン上で

In [66]: %timeit df.groupby(df.individual).apply(foo) 
100 loops, best of 3: 2.57 ms per loop 

In [67]: %timeit df.groupby(df.individual).apply(bar) 
100 loops, best of 3: 2.16 ms per loop 
を高速化(〜20%)、小型がありました