使用标准在 python pandas 中进行内部连接
Posted
技术标签:
【中文标题】使用标准在 python pandas 中进行内部连接【英文标题】:Do an inner join in python pandas using criteria 【发布时间】:2016-11-11 14:18:35 【问题描述】:我试图在 python/pandas 中复制在 SQL 中相当简单的内容,但我卡住了。
我想取一个三列的数据框:
dataframe1
Org Des Score
0 A B 10
1 A B 11
2 A B 15
3 A C 4
4 A C 4.5
5 A C 6
6 A D 100
7 A D 110
8 A D 130
并为每个 Org-Des 组合过滤掉所有大于最小值 * 1.2 的分数值。
所以输出表是:
output_dataframe
Org Des Score
0 A B 10
1 A B 11
3 A C 4
4 A C 4.5
6 A D 100
7 A D 110
对于第一个 Org-Des 组合 AB,最小分数为 10 且 (1.2 * min) = 12。因此第 0 行和第 1 行将被保留,因为分数 10 和 11 小于 12。第 3 行将被删除,因为大于 12。
对于 A-C,最小分数为 4 且 (1.2 * min) = 5。因此第 3 行和第 4 行被保留,因为它们
我的方法
我想我会使用以下方法:
使用 groupby 函数通过 Org-Des 对创建具有 mins 的数据框:
dataframe2 = pd.DataFrame(dataframe1.groupby(['Org','Des'])['Score'].min())
然后在 dataframe1 和 dataframe2 之间进行内部连接(或合并?),标准是每个 Org-Des 对类型的 Score
但是由于两个原因,我无法让它工作,1) dataframe2 最终成为一个时髦的形状,我需要弄清楚如何加入或与 dataframe1 合并,或者先转换然后加入/合并2)我不知道如何将标准设置为加入/合并的一部分。
这是正确的方法还是有更 Pythonic 的方法来实现相同的目标?
编辑以反映@Psidom 答案:
我尝试了您建议的代码,但它给了我一个错误,这是完整的代码和输出:
In: import pandas as pd
import numpy as np
In: df1 = pd.DataFrame('Org': ['A','A','A','A','A','A','A','A','A'],
'Des': ['B','B','B','C','C','C','D','D','D'],
'Score': ['10','11','15','4','4.5','6','100','110','130'], )
Out: Org Des Score
0 A B 10
1 A B 11
2 A B 15
3 A C 4
4 A C 4.5
5 A C 6
6 A D 100
7 A D 110
8 A D 130
In: df2 = pd.DataFrame(df1.groupby(['Org','Des'])['Score'].min())
df2
Out: Score
Org Des
A B 10
C 4
D 100
In: df1 = pd.merge(df1, df2.groupby(['Org', 'Des']).min()*1.2, left_on = ['Org', 'Des'], right_index=True)
df.loc[df1.Score_x < df1.Score_y, :]
Out: KeyError: 'Org' #It's a big error but this seems to be the relevant part. Let me know if it would be useful to past the whole error.
我怀疑我可能把 df1、df2 和 df 搞混了?我从原始答案帖子更改以匹配代码。
【问题讨论】:
【参考方案1】:您可以这样设置加入条件。对于原始数据框,将连接列设置为['Org', 'Des']
,对于聚合数据框,分组列成为索引,因此您需要将right_index
设置为true,然后它应该可以按预期工作:
import pandas as pd
df1 = pd.DataFrame('Org': ['A','A','A','A','A','A','A','A','A'],
'Des': ['B','B','B','C','C','C','D','D','D'],
'Score': [10,11,15,4,4.5,6,100,110,130])
df2 = pd.DataFrame(df1.groupby(['Org','Des'])['Score'].min())
df3 = pd.merge(df1, df2, left_on = ['Org', 'Des'], right_index=True)
df1.loc[df3.Score_x < df3.Score_y * 1.2, ]
# Org Des Score
#0 A B 10.0
#1 A B 11.0
#3 A C 4.0
#4 A C 4.5
#6 A D 100.0
#7 A D 110.0
【讨论】:
我尝试了您建议的代码,并编辑了上面的问题以反映 a) 我正在使用的完整代码和 b) 它给我的错误。知道我做错了什么吗?请注意,我更改了代码中的 df 名称以匹配我为数据框命名的名称。我可能错过了什么。 刚刚使答案可重现,您得到了错误,因为您计算了groupby min()
两次。如果您的df2
已经通过groupby-min
操作计算,那么您只需将其传递给pd.merge()
的第二个位置。
成功了,谢谢!此外,我编辑了我的原始帖子,在那里我错误地将分数列创建为一堆字符串。这给了我一个错误。输入它们作为值修复它。【参考方案2】:
我是这样做的:
df[df.groupby(['Org', 'Des']).Score.apply(lambda x: x < x.min() * 1.2)]
【讨论】:
这很漂亮。我不熟悉 lambda 函数,但这确实有效。用更少的代码。将研究 lambdas。此外,大于、小于符号被颠倒了,所以它给出了相反的答案,但翻转它起作用了。以上是关于使用标准在 python pandas 中进行内部连接的主要内容,如果未能解决你的问题,请参考以下文章
连接大型 CSV 文件中单词的最有效方法:pandas 还是 Python 标准库? [复制]