我有一个任意长度的Pandas系列列表:
s = pd.Series([[1,2,3], [4,6], [7,8,9,10]])
和元素列表
l = [1,2,3,6,7,8]
我想返回包含l
中所有值的序列s
的所有元素,否则返回None
。我想做这样的事情但是要把它应用到序列中的每个元素上:
s.where(s.isin(l), None)
那么输出将是一个序列:
pd.Series([[1,2,3], None, None])
你可以使用python集合的魔力:
s.apply(set(l).issuperset)
输出:
0 True
1 False
2 False
dtype: bool
然后使用where
修改不匹配的行,使用前面的输出作为掩码:
s.where(s.apply(set(l).issuperset), None)
输出:
0 [1, 2, 3]
1 None
2 None
dtype: object
您可以使用explode
系列,使用isin
与l,使用all
与参数level=0(相当于索引上的groupby.all
)。
print(s.explode().isin(l).all(level=0))
0 True
1 False
2 False
dtype: bool
在where
中使用布尔掩码来获得预期的结果
s1 = s.where(s.explode().isin(l).all(level=0), None)
print(s1)
0 [1, 2, 3]
1 None
2 None
dtype: object
由于@mozway的注释,参数level=0在all中被弃用,所以解决方案是使用groupby.all
s1 = s.where(s.explode().isin(l).groupby(level=0).all(), None)
@TomNash,您可以将all
功能与listcomprehension
功能结合使用:
s = pd.Series([[1,2,3], [4,5,6], [7,8,9]])
l = [1,2,3,6,7,8]
final_list = []
for x in s:
if all(item in l for item in x):
final_list.append(x)
else:
final_list.append(None)
print(final_list)
输出:
[[1, 2, 3], None, None]
s = pd.Series([[1,2,3], [4,6], [7,8,9,10]])
l = [1,2,3,6,7,8]
new_series = []
for i in range(len(s)):
s_in_l = 0
for j in range(len(s[i])):
if s[i][j] not in l:
s_in_l = s_in_l + 1
if s_in_l == 0:
new_series.append(s[i])
else:
new_series.append(None)
new_series = pd.Series(new_series)
print(new_series)
输出:
0 [1, 2, 3]
1 None
2 None
dtype: object
可以通过.issubset
函数检查s
的元素是否为l
的子集,如下所示:
s.apply(lambda x: x if set(x).issubset(l) else None)
或使用numpy函数setdiff1d
,如下所示:
s.apply(lambda x: x if (len(np.setdiff1d(x, l)) == 0) else None)
结果:
0 [1, 2, 3]
1 None
2 None
dtype: object