首页 > 解决方案 > 在非空行上过滤数据框

问题描述

我有一个来自这种形式的 DataFrame:

In [122]: df=pd.DataFrame({"A":["1,2,3","4,5,6",np.nan,"8"],"B":[6,7,8,9]})

In [123]: df
Out[123]:
       A  B
0  1,2,3  6
1  4,5,6  7
2    NaN  8
3      8  9

我想过滤 B 中的行,其中 A 中的列表包含特定值,例如“4”。

我尝试使用这种语法:

df["B"][["4" in a for a in df["A"].str.split(',')]]

但我得到TypeError: argument of type 'float' is not iterable是因为NaN其中一条线。所以我尝试了这种语法-

df["B"][["4" in a for a in df["A"].str.split(',') if pd.notnull(a)]]

但我明白了ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

知道如何使它工作吗?我尝试了一些想法,但都没有奏效,我真的不知道为什么这种语法是错误的。

预期产出 - 7.

标签: pythonpandasdataframe

解决方案


使用熊猫替代品:

s = df.loc[df["A"].str.split(',', expand=True).eq('4').any(axis=1), 'B']
print (s)
1    7
Name: B, dtype: int64

说明

expand=True通过in参数创建 DataFrame Series.str.split

print (df["A"].str.split(',', expand=True))
     0     1     2
0    1     2     3
1    4     5     6
2  NaN   NaN   NaN
3    8  None  None

比较DataFrame.eq( ==):

print (df["A"].str.split(',', expand=True).eq('4'))
       0      1      2
0  False  False  False
1   True  False  False
2  False  False  False
3  False  False  False

True通过以下方式检查每行是否至少有一个DataFrame.any

print (df["A"].str.split(',', expand=True).eq('4').any(axis=1))
0    False
1     True
2    False
3    False
dtype: bool

DataFrame.loc最后用with过滤boolean indexing

您的解决方案应更改为if-elseand isinstance

mask = ["4" in a if isinstance(a, list) else False for a in df["A"].str.split(',')]

s = df.loc[mask, 'B']

推荐阅读