2015-05-14 89 views
0

我有一張短語表,並且有一張組成這些短語的單個詞表。我想將我的短語分解爲單個單詞,收集和減少這些單詞的信息,並添加爲我的短語數據中的新列。有沒有一個聰明的方式來使用熊貓DataFrames做到這一點?將大熊貓DataFrame列拆分爲多個部分並與其他DataFrame結合

df_multigram = pd.DataFrame([ 
     ["happy birthday", 23], 
     ["used below", 10], 
     ["frame for", 2] 
    ], columns=["multigram", "frequency"]) 
    df_onegram = pd.DataFrame([ 
     ["happy", 35], 
     ["birthday", 25], 
     ["used", 14], 
     ["below", 11], 
     ["frame", 2], 
     ["for", 13] 
    ], columns=["onegram", "frequency"]) 

    ###### What do I do here????? ####### 

    sum_freq_onegrams = list(df_multigram["sum_freq_onegrams"]) 
    self.assertEqual(sum_freq_onegrams, [60, 25, 15]) 

只是爲了澄清,我的願望是,sum_freq_onegrams等於[60,25,15],其中60是「快樂」加「生日」的頻率的頻率。

回答

3

你可以使用

freq = df_onegram.set_index(['onegram'])['frequency'] 
sum_freq_onegrams = df_multigram['multigram'].str.split().apply(
    lambda x: pd.Series(x).map(freq).sum()) 

這將產生

In [43]: sum_freq_onegrams 
Out[45]: 
0 60 
1 25 
2 15 
Name: multigram, dtype: int64 

但請注意,調用(拉姆達)每行一次,每次構建一個新的(微小)系列可能會相當緩慢。使用不同的數據結構 - 甚至是純Python列表和字典 - 可能會更快。例如,如果定義了列表phrases和字典freq_dict

phrases = df_multigram['multigram'].tolist() 
freq_dict = freq.to_dict() 

則列表理解(下面)比基於熊貓-方法快280X:

In [65]: [sum(freq_dict.get(item, 0) for item in phrase.split()) for phrase in phrases] 
Out[65]: [60, 25, 15] 

In [38]: %timeit [sum(freq_dict.get(item, 0)for item in phrase.split()) for phrase in phrases] 
100000 loops, best of 3: 3.6 µs per loop 

In [41]: %timeit df_multigram['multigram'].str.split().apply(lambda x: pd.Series(x).map(freq).sum()) 
1000 loops, best of 3: 1.01 ms per loop 

因此,使用熊貓DataFrame在這裏保存這些短語可能不是這個問題的正確數據結構。

1

有可能是一個更好的辦法做到這一點,但這個工程:

In [131]: 

def func(x): 
    total = 0 
    for w in x.split(): 
     if len(df_onegram[df_onegram['onegram'] == w]) > 0: 
      total += df_onegram[df_onegram['onegram'] == w]['frequency'].values[0] 
    return total 
df_multigram['total_freq'] = df_multigram['multigram'].apply(lambda x: func(x)) 
df_multigram 
Out[131]: 
     multigram frequency total_freq 
0 happy birthday   23   60 
1  used below   10   25 
2  frame for   2   15