Skip to main content
 首页 » 编程设计

python之在多列上过滤 Pandas 数据框的最快方法

2025年05月04日9sky-heaven

我有一个 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 

和一个元组列表,

list_t = [('a1','a2','a3'), ('d1','d2','d3')] 

我想过滤这个数据框并返回一个新的数据框,其中只包含与我的列表中的元组对应的行。

result =        1_label 2_label 3_label  data 
            0      a1      a2      a3     1 
            1      d1      d2      d3     4 

我天真的(和 C++ 启发的)解决方案是使用追加(如 vector::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)] 

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

请您参考如下方法:

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

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