我有一个短语表,我有一个组成这些短语的单个单词表。我想把我的短语分解成单个单词,收集和减少关于这些单个单词的信息,并将其作为新列添加到我的短语数据中。是否有一个聪明的方法来做到这一点使用熊猫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是"happy"的频率加上"birthday"的频率。
你可以使用
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
但是请注意,每行调用一次(lambda)函数并每次构建一个新的(很小的)Series可能会相当慢。使用不同的数据结构——甚至是普通的Python列表和字典——可能会更快。例如,如果您定义了列表phrases
和字典freq_dict
,
phrases = df_multigram['multigram'].tolist()
freq_dict = freq.to_dict()
则列表推导(如下)比基于pandas的方法快280倍:
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
因此,在这里使用Pandas DataFrame来保存短语可能不是解决这个问题的正确数据结构。
可能有更好的方法来做到这一点,但这是有效的:
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