从熊猫系列中删除少于4个字符的单词

时间:2017-03-31 21:34:30

标签: python pandas parsing nlp

我正在尝试从Pandas系列中的每个标量值中删除少于4个字符的所有单词。最好的方法是什么?这是我失败的尝试:

df['text'] = df['text'].str.join(word for word in df['text'].str.split() if len(word)>3)

我收到以下错误消息:

  

AttributeError:'generator'对象没有属性'join'

我根据字符串中的相同内容对此帖子进行了尝试:Remove small words using Python

附注:如果在删除少于4个字符之前更好地标记我的单词,请告诉我。

编辑:每个标量值都包含句子,因此我想删除值中长度小于4的任何单词。

4 个答案:

答案 0 :(得分:5)

您可以这样做:

>>> df = pd.DataFrame({'text':["The quick brown fox", "jumped over the lazy dog"]})
>>> df
                       text
0       The quick brown fox
1  jumped over the lazy dog
>>> df['text'].str.split().map(lambda sl: " ".join(s for s in sl if len(s) > 3))
0         quick brown
1    jumped over lazy
Name: text, dtype: object

但说实话,我经常坚持使用vanilla python进行文本处理。 pandas数据结构不能很好地与文本配合使用。至少,您正在失去numpy / pandas的内存/速度优势。

答案 1 :(得分:4)

使用.str.findall.str.join的正则表达式似乎最快:

df['text'].str.findall('\w{4,}').str.join(' ')

<强>计时

使用以下设置:

df = pd.DataFrame({'text':["The quick brown fox", "jumped over the lazy dog", "foo bar baz", 'words exceeding desired length']})
df = pd.concat([df]*10**4, ignore_index=True)

def pir2(df):
    t = df.text.str.split(expand=True).stack()
    return t.loc[t.str.len() >= 4].groupby(level=0).apply(' '.join)

我得到以下时间:

%timeit df['text'].str.findall('\w{4,}').str.join(' ')
10 loops, best of 3: 44.8 ms per loop

%timeit df.text.apply(lambda i: ' '.join(filter(lambda j: len(j) > 3, i.split())))
10 loops, best of 3: 79.3 ms per loop

%timeit df['text'].str.split().map(lambda sl: " ".join(s for s in sl if len(s) > 3))
10 loops, best of 3: 87.2 ms per loop

%timeit pir2(df)
1 loop, best of 3: 2.87 s per loop

答案 2 :(得分:2)

考虑@ juanpa.arrivillaga&#39; dataframe df

df = pd.DataFrame({'text':["The quick brown fox", "jumped over the lazy dog"]})

然后我们可以

t = df.text.str.split(expand=True).stack()
t.loc[t.str.len() >= 4].groupby(level=0).apply(' '.join)

0         quick brown
1    jumped over lazy
dtype: object

答案 3 :(得分:1)

尝试

df.test.apply(lambda i: ' '.join(filter(lambda j: len(j) > 3, i.split())))