Pandas,如何使用带有多索引数据框的子集来删除值?
Pandas, how to dropna values using subset with multiindex dataframe?
我有一个包含多索引列的数据框。
我需要从此数据框中删除列子集中具有 NaN 值的行。
我正在尝试使用 pd.dropna
的 subset
选项,但我没能找到指定列子集的方法。我试过使用 pd.IndexSlice
但这不起作用。
在下面的示例中,我需要搭乘最后一排。
import pandas as pd
# ---
a = [1, 1, 2, 2, 3, 3]
b = ["a", "b", "a", "b", "a", "b"]
col = pd.MultiIndex.from_arrays([a[:], b[:]])
val = [
[1, 2, 3, 4, 5, 6],
[None, None, 1, 2, 3, 4],
[None, 1, 2, 3, 4, 5],
[None, None, 5, 3, 3, 2],
[None, None, None, None, 5, 7],
]
# ---
df = pd.DataFrame(val, columns=col)
# ---
print(df)
# ---
idx = pd.IndexSlice
df.dropna(axis=0, how="all", subset=idx[1:2, :])
# ---
print(df)
使用 thresh
选项是一种替代方法,但如果可能的话,我想使用 subset
和 how='all'
在处理MultiIndex时,MultiIndex的每一列都可以指定为一个元组:
In [67]: df.dropna(axis=0, how="all", subset=[(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')])
Out[67]:
1 2 3
a b a b a b
0 1.0 2.0 3.0 4.0 5 6
1 NaN NaN 1.0 2.0 3 4
2 NaN 1.0 2.0 3.0 4 5
3 NaN NaN 5.0 3.0 3 2
或者,对于 select 第一级等于 1
或 2
的所有列,您可以使用:
In [69]: df.dropna(axis=0, how="all", subset=df.loc[[], [1,2]].columns)
Out[69]:
1 2 3
a b a b a b
0 1.0 2.0 3.0 4.0 5 6
1 NaN NaN 1.0 2.0 3 4
2 NaN 1.0 2.0 3.0 4 5
3 NaN NaN 5.0 3.0 3 2
df[[1,2]].columns
也可以,但是这个 returns 是一个(可能很大的)中间 DataFrame。 df.loc[[], [1,2]].columns
更节省内存,因为它的中间 DataFrame 是空的。
如果要将dropna
应用到级别1中有1或2的列,您可以按如下方式进行:
cols= [(c0, c1) for (c0, c1) in df.columns if c0 in [1,2]]
df.dropna(axis=0, how="all", subset=cols)
如果应用于您的数据,结果为:
Out[446]:
1 2 3
a b a b a b
0 1.0 2.0 3.0 4.0 5 6
1 NaN NaN 1.0 2.0 3 4
2 NaN 1.0 2.0 3.0 4 5
3 NaN NaN 5.0 3.0 3 2
如您所见,最后一行 (index=4) 不见了,因为 1 和 2 以下的所有列都是此行的 NaN
。如果您希望删除列中出现任何 NaN
的所有行,您需要:
df.dropna(axis=0, how="any", subset=cols)
这导致:
Out[447]:
1 2 3
a b a b a b
0 1.0 2.0 3.0 4.0 5 6
我有一个包含多索引列的数据框。
我需要从此数据框中删除列子集中具有 NaN 值的行。
我正在尝试使用 pd.dropna
的 subset
选项,但我没能找到指定列子集的方法。我试过使用 pd.IndexSlice
但这不起作用。
在下面的示例中,我需要搭乘最后一排。
import pandas as pd
# ---
a = [1, 1, 2, 2, 3, 3]
b = ["a", "b", "a", "b", "a", "b"]
col = pd.MultiIndex.from_arrays([a[:], b[:]])
val = [
[1, 2, 3, 4, 5, 6],
[None, None, 1, 2, 3, 4],
[None, 1, 2, 3, 4, 5],
[None, None, 5, 3, 3, 2],
[None, None, None, None, 5, 7],
]
# ---
df = pd.DataFrame(val, columns=col)
# ---
print(df)
# ---
idx = pd.IndexSlice
df.dropna(axis=0, how="all", subset=idx[1:2, :])
# ---
print(df)
使用 thresh
选项是一种替代方法,但如果可能的话,我想使用 subset
和 how='all'
在处理MultiIndex时,MultiIndex的每一列都可以指定为一个元组:
In [67]: df.dropna(axis=0, how="all", subset=[(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')])
Out[67]:
1 2 3
a b a b a b
0 1.0 2.0 3.0 4.0 5 6
1 NaN NaN 1.0 2.0 3 4
2 NaN 1.0 2.0 3.0 4 5
3 NaN NaN 5.0 3.0 3 2
或者,对于 select 第一级等于 1
或 2
的所有列,您可以使用:
In [69]: df.dropna(axis=0, how="all", subset=df.loc[[], [1,2]].columns)
Out[69]:
1 2 3
a b a b a b
0 1.0 2.0 3.0 4.0 5 6
1 NaN NaN 1.0 2.0 3 4
2 NaN 1.0 2.0 3.0 4 5
3 NaN NaN 5.0 3.0 3 2
df[[1,2]].columns
也可以,但是这个 returns 是一个(可能很大的)中间 DataFrame。 df.loc[[], [1,2]].columns
更节省内存,因为它的中间 DataFrame 是空的。
如果要将dropna
应用到级别1中有1或2的列,您可以按如下方式进行:
cols= [(c0, c1) for (c0, c1) in df.columns if c0 in [1,2]]
df.dropna(axis=0, how="all", subset=cols)
如果应用于您的数据,结果为:
Out[446]:
1 2 3
a b a b a b
0 1.0 2.0 3.0 4.0 5 6
1 NaN NaN 1.0 2.0 3 4
2 NaN 1.0 2.0 3.0 4 5
3 NaN NaN 5.0 3.0 3 2
如您所见,最后一行 (index=4) 不见了,因为 1 和 2 以下的所有列都是此行的 NaN
。如果您希望删除列中出现任何 NaN
的所有行,您需要:
df.dropna(axis=0, how="any", subset=cols)
这导致:
Out[447]:
1 2 3
a b a b a b
0 1.0 2.0 3.0 4.0 5 6