将pandas的DataFrame列分解为多个部分,并与其他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是"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

最新更新