如果其中一个单元格包含所有大写字符串的列表,则从 pandas 数据框中删除行

Removing a rows from pandas data frame if one of its cell contains list of all caps string

我正在使用 conll2003 数据集。它包含来自各种新闻来源的文章等。它包含句子、这些句子中每个单词的词性标记、这些单词的块 ID 等。

有些句子全部大写。我只是想从相应的数据框中删除这些行。这是我尝试过的:

import re

df_train = conll2003dataset['train'].to_pandas()
df_test = conll2003dataset['test'].to_pandas()

all_caps_regex = re.compile('^[^a-z]*$')

df_train.drop(df_train[all(map(all_caps_regex.search, df_train['tokens']))].index, inplace=True)
df_test.drop(df_test[all(map(all_caps_regex.search, df_test['tokens']))].index, inplace=True)

但我收到以下错误:

TypeError                                 Traceback (most recent call last)
<ipython-input-17-feda9c78b1c7> in <module>()
      9 all_caps_regex = re.compile('^[^a-z]*$')
     10 
---> 11 df_train.drop(df_train[all(map(all_caps_regex.search, df_train['tokens']))].index, inplace=True)
     12 df_test.drop(df_test[all(map(all_caps_regex.search, df_test['tokens']))].index, inplace=True)
     13 

TypeError: cannot use a string pattern on a bytes-like object

我哪里错了?我该怎么做?

Here 是说明相同内容的 colab 笔记本。

问题是系列“df_train”中的每个元素都是一个列表,因此您将正则表达式应用于列表而不是列表中的元素。为此,您需要遍历列表的元素,如下所示:

df_train[ [all(map(all_caps_regex.search, w)) for w in df_train['tokens']] ].index

话虽如此,但由于我们使用的是pandas,所以建议使用pandas的方法,通常更快更实用。我们可以使用 .map() 或 .apply():

将函数映射到 Series 的每个元素
df_train[ df_train['tokens'].apply(lambda l:all([all_caps_regex.search(w) for w in l])) ]

最后一个解决方案是根本不使用正则表达式,因为我们需要做的就是检查每个元素是否大写。为此,我们可以检查 text.upper() 是否与未修改的文本相同:

df_train[ df_train['tokens'].apply(lambda l:[w.upper() for w in l] == [w for w in l]) ].index