Pandas DataFrame-如何删除包含特定列空值的整个类别



让我们假设我有以下DataFrame:

单词_每个页面第2册
书籍 页面字符
第1册
第1册 2
第1册 2 30 25
第2册22830

您可以找到两个值中任意一个为NaN的行,然后使用~运算符从df中排除这些行

import pandas as pd
import numpy as np
df = pd.DataFrame({'book': ['Book 1', 'Book 1', 'Book 1', 'Book 2', 'Book 2'],
'page': [1, 2, 2, 1, 2],
'words_per_page': ['27', np.nan, '30', '30', '28'],
'characters': [np.nan, '30', '25', '26', '30']})
books_with_nulls = df.loc[df[['words_per_page','characters']].isnull().any(axis=1)]['book'].unique()
df.loc[~df['book'].isin(books_with_nulls)]

识别符合该标准的图书ID,并使用这些图书ID过滤DF,例如

import pandas as pd
data = [
[1, 1, 27, None],
[1, 2, None, 30],
[1, 2, 30, 25],
[2, 1, 30, 26],
[2, 2, 28, 30]
]
columns = [
'book_id',
'page_number',
'words_per_page',
'character_count'
]
df = pd.DataFrame(data, columns=columns)
df = df[~df.book_id.isin(
df[
(df.words_per_page.isna()) |
(df.character_count.isna())
].book_id
)].copy()
book_id  page_number words_per_page  character_count
3  2        1           30.0            26.0
4  2        2           28.0            30.0

您可以使用groupbyfilter来删除未通过筛选的整个组/书籍。这里的过滤器是每个图书组必须是Words_per_pagecharactersall值中的notnull

import pandas as pd
import numpy as np
df = pd.DataFrame({
'book': ['Book 1', 'Book 1', 'Book 1', 'Book 2', 'Book 2'],
'page': [1, 2, 2, 1, 2],
'words_per_page': [27, np.nan, 30, 30, 28],
'characters': [np.nan, 30, 25, 26, 30]
})
filt_df = (
df.groupby('book').filter(
lambda b: b['words_per_page'].notnull().all() and b['characters'].notnull().all() 
)
)
filt_df

groupby.filter在大型数据集上速度慢是出了名的,不确定它是否足够快来满足您的用例

这里有一种方法可以实现

df.dropna(axis=0, how='any')

或者如果只有列的子集要检查空值

df.dropna(subset=['words_per_page','characters'], axis=0, how='any')

book    page    words_per_page  characters
2   Book 1    2                 30          25
3   Book 2    1                 30          26
4   Book 2    2                 28          30

最新更新