在 Panda DataFrame 中过滤 groupby 数据的有效方法
Posted
技术标签:
【中文标题】在 Panda DataFrame 中过滤 groupby 数据的有效方法【英文标题】:Efficient way of filtering groupby data in a Panda DataFrame 【发布时间】:2019-09-12 00:14:50 【问题描述】:问题
我有两个数据框Frame A
(保存一些原始数据)和Frame B
(保存阈值数据)。
我的目标是针对Frame B
中的每个ID 我想返回Frame A
中对应ID 的行<= b['A']
。
我写的代码运行良好,我的问题是效率。框架 B 有大约 100K 行,而框架 A 有大约 1M 行。根据快速计算,我需要大约 6 个小时来过滤我的数据。虽然 6 小时可能是可行的(我可以让它在一夜之间运行),但这个数据集代表了我数据的一小部分样本,约占我总数据集的 5%。
我的尝试
import pandas as pd
from io import StringIO
data1 = """
id,A,B,C,D
123,2019-09-10 00:00:00,1,True,False
123,2019-09-10 00:10:00,1,True,False
123,2019-09-11 00:07:00,1,True,False
456,2019-09-05 01:00:00,1,True,False
456,2019-09-08 10:00:00,1,True,False
789,2019-09-10 10:00:00,1,True,False
789,2019-09-11 00:50:00,1,True,False
789,2019-09-12 12:00:00,1,True,False
"""
data2 = """
id,A,B
123,2019-09-10 00:10:00,1
456,2019-09-05 01:00:00,1
789,2019-09-12 12:00:00,1
"""
df_a = pd.read_csv(StringIO(data1))
df_b = pd.read_csv(StringIO(data2))
dfs = []
for Id in df_b.id.unique():
df = df_a[df_a.id == Id]
df = df[df['A'] <= df_b[df_b.id == Id]['A'].values[0]]
dfs.append(df)
print(pd.concat(dfs))
数据
期望的输出
id A B C D
0 123 2019-09-10 00:00:00 1 True False
1 123 2019-09-10 00:10:00 1 True False
3 456 2019-09-05 01:00:00 1 True False
5 789 2019-09-10 10:00:00 1 True False
6 789 2019-09-11 00:50:00 1 True False
7 789 2019-09-12 12:00:00 1 True False
A 帧
id A B C D
0 123 2019-09-10 00:00:00 1 True False
1 123 2019-09-10 00:10:00 1 True False
2 123 2019-09-11 00:07:00 1 True False
3 456 2019-09-05 01:00:00 1 True False
4 456 2019-09-08 10:00:00 1 True False
5 789 2019-09-10 10:00:00 1 True False
6 789 2019-09-11 00:50:00 1 True False
7 789 2019-09-12 12:00:00 1 True False
帧 B
id A B
0 123 2019-09-10 00:10:00 1
1 456 2019-09-05 01:00:00 1
2 789 2019-09-12 12:00:00 1
【问题讨论】:
将您的数据放入任何 SQL 数据库并在那里执行。 @AidanGawronski,必须解决基础架构限制和跨团队/环境的复制问题 :) 【参考方案1】:使用map
s = df_a.id.map(dict(df_b[['id', 'A']].values))
df_a[df_a.A <= s]
Out[35]:
id A B C D
0 123 2019-09-10 00:00:00 1 True False
1 123 2019-09-10 00:10:00 1 True False
3 456 2019-09-05 01:00:00 1 True False
5 789 2019-09-10 10:00:00 1 True False
6 789 2019-09-11 00:50:00 1 True False
7 789 2019-09-12 12:00:00 1 True False
使用左边的merge
和query
(df_a.merge(df_b[['id', 'A']], on='id', how='left', suffixes=('','_y'))
.query('A <= A_y').drop('A_y', 1))
Out[43]:
id A B C D
0 123 2019-09-10 00:00:00 1 True False
1 123 2019-09-10 00:10:00 1 True False
3 456 2019-09-05 01:00:00 1 True False
5 789 2019-09-10 10:00:00 1 True False
6 789 2019-09-11 00:50:00 1 True False
7 789 2019-09-12 12:00:00 1 True False
【讨论】:
太棒了,很棒的解决方案,超级快! @Teddy:很高兴我能帮上忙 :)。我还赞成你关于清晰、详细的信息和样本的问题。你显然是在准备问题上付出了努力。 +1以上是关于在 Panda DataFrame 中过滤 groupby 数据的有效方法的主要内容,如果未能解决你的问题,请参考以下文章
Pandas 使用 DataFrame.query 根据字符串长度过滤字符串数据
如何在 Panda MultiIndex Dataframe 中绘制 ylabel