如果特定年份的列中存在NaN值,请删除这些行。

3

我想要删除在2019年和2020年中,第一列、第二列和第三列包含NaN值的行。

以下是数据框:

col1     col2     col3     col4     year
NaN      NaN      NaN      NaN      2018
NaN      NaN      NaN      NaN      2019
NaN      NaN      NaN      100      2019
100      200      100      NaN      2020
NaN      NaN      NaN      200      2020
100      100      150      150      2021

期望结果:

col1     col2     col3     col4     year
NaN      NaN      NaN      NaN      2018
100      200      100      NaN      2020
100      100      150      150      2021

我尝试过这个,但是它无法正常工作:
df.drop(df[(df['year'] == [2019, 2020]) 
                            & (df[['col1', 'col2', 'col3']].isnull())].index, inplace=True)

你能提供这个数据框的表达式,这样我就可以处理它了吗? - Wael Jlassi
3个回答

2

你需要使用isin方法来检查多个值,并使用all方法将布尔型DataFrame合并成一个Series:

# is the year 2019 or 2020?
m1 = df['year'].isin([2019, 2020])
# are all the values in col1/col2/col3 null for a given row?
m2 = df[['col1', 'col2', 'col3']].isnull().all(1)

# invert the above two conditions to select rows to keep
df = df[~(m1&m2)]

# or
# df.drop(df[m1&m2].index, inplace=True)

输出:

    col1   col2   col3   col4  year
0    NaN    NaN    NaN    NaN  2018
3  100.0  200.0  100.0    NaN  2020
5  100.0  100.0  150.0  150.0  2021

1
df.loc[~(df[["col1", "col2", "col3"]].isna().all(axis="columns")
         & df["year"].isin([2019, 2020]))]

条件如下:

第1、2和3列中存在NaN值

df[["col1", "col2", "col3"]].isna().all(axis="columns")

年份为2019和2020。
df["year"].isin([2019, 2020])

然后,对这些进行&运算,反转结果并与其索引一起使用;最终我们将得到所需的行。

1

由于您要基于yearnan的值进行过滤,因此您可能需要拆分数据框并重新合并。

msk = df['year'].isin([2019, 2020]) # drop where True, keep the complement as-is
df_oth = df[~msk]
df_req = df[msk].dropna(how='all', subset=['col1', 'col2', 'col3'])
df_out = pd.concat([df_oth, df_req])

输出

    col1   col2   col3   col4  year
0    NaN    NaN    NaN    NaN  2018
5  100.0  100.0  150.0  150.0  2021
3  100.0  200.0  100.0    NaN  2020

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接