繁体   English   中英

如何使用 pd.DataFrame 过滤不同的 pd.DataFrame

[英]How to use a pd.DataFrame for filtering a different pd.DataFrame

我有一个 pandas DataFrame 包含数据和另一个 DataFrame ,其中每一行都可以解释为数据的过滤器:

data_df = pd.DataFrame([{'a':i%10, 'b':i%15} for i in range(30)])

filter_df = pd.DataFrame({'a':[3,4,5], 'b0':[5,6,8], 'b1':[15,10,11]})
filter_df
    a   b0  b1
0   3   5   15
1   4   6   10
2   5   8   11

意思是

pd.concat([
data_df[(data_df.a==3) & data_df.b.between(5,15)],
data_df[(data_df.a==4) & data_df.b.between(6,10)],
data_df[(data_df.a==5) & data_df.b.between(8,11)]
])

现在我需要一种将所有这些过滤器应用到 data_df 并得到 DataFrame 的方法。 一种方法是使用 apply:

res = filter_df.apply(lambda x: data_df[(data_df.a==x['a']) & data_df.b.between(x['b0'], x['b1'])], axis=1)
res = pd.concat([x for x in res])

请注意,要使其正常工作,我必须连接结果列表,因为结果是包含每行返回值的系列,可能是无、pd.Series 或 pd.DataFrame。 有一个更好的方法吗? 我希望有类似.reset_index() 的东西,但似乎我找不到正确的方法。 另外,如果有比 apply 更优雅/不同的方式,我会很高兴。 实际上,data_df 将在数百千或数百万行中,而我希望 filter_df 低于 1000 行,但大多数时候超过 10 行,如果这对性能有影响的话

可以合并查询:

data_df.merge(filter_df, on='a', how='right').query('b0 <= b <= b1')

或者等效地,合并和定位过滤器:

(data_df.merge(filter_df, on='a', how='right')
        .loc[lambda x: x['b'].between(x['b0'], x['b1'])]
)

Output:

   a   b  b0  b1
1  3  13   5  15
2  3   8   5  15
5  4   9   6  10
8  5  10   8  11

您可以使用 boolean 索引:

d = filter_df.set_index('a')

# is "a" in filter_df's a?
m1 = data_df['a'].isin(filter_df['a'])
# is b ≥ the matching b0 value in filter_df?
m2 = data_df['b'].ge(data_df['a'].map(d['b0']))
# is b ≤ the matching b1 value in filter_df?
m3 = data_df['b'].le(data_df['a'].map(d['b1']))

# keep if all conditions are True
data_df[m1&m2&m3]

output:

    a   b
13  3  13
23  3   8
24  4   9
25  5  10

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM