在多列上过滤 pandas 数据框的最快方法

Roa*_*ord 2 python pandas

我有一个包含几列的 pandas 数据框,用于在最后一列中标记数据,例如,

df = pd.DataFrame( {'1_label' : ['a1','b1','c1','d1'],
                    '2_label' : ['a2','b2','c2','d2'],
                    '3_label' : ['a3','b3','c3','d3'],
                    'data'    : [1,2,3,4]})

df =      1_label 2_label 3_label  data
     0      a1      a2      a3     1
     1      b1      b2      b3     2
     2      c1      c2      c3     3
     3      d1      d2      d3     4
Run Code Online (Sandbox Code Playgroud)

和一个元组列表,

list_t = [('a1','a2','a3'), ('d1','d2','d3')]
Run Code Online (Sandbox Code Playgroud)

我想过滤此数据帧并返回一个新数据帧,其中仅包含与列表中的元组相对应的行。

result =        1_label 2_label 3_label  data
            0      a1      a2      a3     1
            1      d1      d2      d3     4
Run Code Online (Sandbox Code Playgroud)

我天真的(和 C++ 启发)解决方案是使用追加(如向量::push_back)

for l1, l2, l3 in list_t:
    if df[(df['1_label'] == l1) & 
          (df['2_label'] == l2) & 
          (df['3_label'] == l3)].empty is False:
        result = result.append(df[(df['1_label'] == l1) & 
                              (df['2_label'] == l2) &
                              (df['3_label'] == l3)]
Run Code Online (Sandbox Code Playgroud)

虽然我的解决方案有效,但我怀疑对于大型数据帧和大型元组列表来说它速度非常慢,因为我认为 pandas 在每次调用追加时都会创建一个新的数据帧。谁能建议一种更快/更干净的方法来做到这一点?谢谢!

ayh*_*han 5

如果我理解正确的话,合并应该可以完成这项工作:

pd.DataFrame(list_t, columns=['1_label', '2_label', '3_label']).merge(df)
Out[73]: 
  1_label 2_label 3_label  data
0      a1      a2      a3     1
1      d1      d2      d3     4
Run Code Online (Sandbox Code Playgroud)


Ilj*_*ilä 5

假设没有重复项,您可以在要“过滤”的列中创建索引:

In [10]: df
Out[10]: 
  1_label 2_label 3_label  data
0      a1      a2      a3     1
1      b1      b2      b3     2
2      c1      c2      c3     3
3      d1      d2      d3     4

In [11]: df.set_index(['1_label', '2_label', '3_label'])\
    .loc[[('a1','a2','a3'), ('d1','d2','d3')]]\
    .reset_index()
Out[11]: 
  1_label 2_label 3_label  data
0      a1      a2      a3     1
1      d1      d2      d3     4
Run Code Online (Sandbox Code Playgroud)