使用标准在 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 中进行内部连接的主要内容,如果未能解决你的问题,请参考以下文章

Python:使用pandas和numpy计算标准差的区别

连接大型 CSV 文件中单词的最有效方法:pandas 还是 Python 标准库? [复制]

使用 Python Pandas 连接两个具有范围条件的表

Pandas 【Chapter 4】

《利用Python进行数据分析》之pandas的时间序列基础

python pandas groupby分组后的数据怎么用