在Python中过滤匹配向量所有值的数据帧

2024-04-25 23:53:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用Python解决this question。在

ID = np.concatenate((np.repeat("A",5),
                    np.repeat("B",4), 
                    np.repeat("C",2)))
Hour = np.array([0,2,5,6,9,0,2,5,6,0,2])
testVector = [0,2,5]    
df = pd.DataFrame({'ID' : ID, 'Hour': Hour})

我们按ID对行进行分组,然后从df中删除所有行,其中{}中的所有值都在该组的Hour列中。我们可以实现以下目标:

^{pr2}$

我想让这段代码尽可能短而高效。有什么改进或替代解决方案的建议?在


Tags: id目标dataframedfnpthisarraypd
3条回答

与MaxU的解决方案类似,但我使用的是系列而不是集合:

testVector = pd.Series(testVector)
df[df.groupby('ID')['Hour'].transform(lambda x: testVector.isin(x).all())]
Out: 
   Hour ID
0     0  A
1     2  A
2     5  A
3     6  A
4     9  A
5     0  B
6     2  B
7     5  B
8     6  B

不过,这里的过滤器可能更惯用:

^{pr2}$
In [99]: test_set = set(testVector)

In [100]: df.loc[df.groupby('ID').Hour.transform(lambda x: set(x) & test_set == test_set)]
Out[100]:
   Hour ID
0     0  A
1     2  A
2     5  A
3     6  A
4     9  A
5     0  B
6     2  B
7     5  B
8     6  B

说明:

lambda x: set(x) & test_set == test_set)函数中,我们为每个组创建一组Hour值:

^{pr2}$

然后我们设置test_set的交集:

In [105]: df.groupby('ID').Hour.apply(lambda x: set(x) & test_set)
Out[105]:
ID
A    {0, 2, 5}
B    {0, 2, 5}
C       {0, 2}
Name: Hour, dtype: object

再与test_set进行比较:

In [106]: df.groupby('ID').Hour.apply(lambda x: set(x) & test_set == test_set)
Out[106]:
ID
A     True
B     True
C    False
Name: Hour, dtype: bool

PS我用.apply()代替.transform只是为了展示它是如何工作的。在

但我们需要使用transform,以便以后使用布尔索引:

In [107]: df.groupby('ID').Hour.transform(lambda x: set(x) & test_set == test_set)
Out[107]:
0      True
1      True
2      True
3      True
4      True
5      True
6      True
7      True
8      True
9     False
10    False
Name: Hour, dtype: bool

首先为Hour列中的每个ID创建{}s。然后^{}表示新的Series,与向量进行比较:

df = df[df['ID'].map(df.groupby(by='ID')['Hour'].apply(set)) >= set(testVector)]
print (df)
   Hour ID
0     0  A
1     2  A
2     5  A
3     6  A
4     9  A
5     0  B
6     2  B
7     5  B
8     6  B

计时

^{pr2}$

相关问题 更多 >