table 异常减少 Pandas 或 SQL

Unusual table reduction in Pandas or SQL

我有一个数据库 table 类似于以下虚假样本(但有数千条记录):

LastName FirstName MiddleInit Company   Team             LogDate
   smith    joseph          a   compA  teama 2015-09-18 23:00:00
   smith    joseph          a   compA  teamb 2015-08-15 04:00:00
   smith    joseph          a   compA  teamc 2015-10-01 02:15:00
    lamb      mary          b   compA  teama 2015-09-15 23:00:00
    lamb      mary          b   compA  teamb 2015-10-04 01:15:00
    lamb      mary          b   compA  teamc 2015-05-01 07:00:00
    brady    thomas         c   compB  teama 2015-10-02 03:15:00
    brady    thomas         c   compB  teamb 2015-09-11 20:00:00
    brady    thomas         c   compB  teamc 2015-06-02 05:00:00
    smith      john         d   compB  teama 2015-09-12 08:00:00
    smith      john         d   compB  teamb 2015-10-05 09:15:00
    smith      john         d   compB  teamc 2015-07-03 15:00:00

包括的人留在同一家公司,但他们从一个团队转到另一个团队。 我有兴趣根据 LogDate 字段找出每个人最近所在的团队。这是我想要生成的输出(名称顺序无关紧要):

LastName FirstName MiddleInit Company   Team             LogDate
   smith    joseph          a   compA  teamc 2015-10-01 02:15:00
    lamb      mary          b   compA  teamb 2015-10-04 01:15:00
   brady    thomas          c   compB  teama 2015-10-02 03:15:00
   smith      john          d   compB  teamb 2015-10-05 09:15:00

我想知道是否有办法使用单个 SQL 查询或使用 Pandas(最好没有循环)来导出此输出.

尝试使用 SQL:我在写这篇文章时无法访问数据库,但我必须加入两个 table 才能获得 Team 字段,我认为我尝试了以下方法但没有成功(这可能不完全正确,但应该接近我的尝试):

SELECT a.LastName, a.FirstName, a.MiddleInit, a.Company, b.Team, max(b.LogDate) FROM table1 AS a JOIN table2 AS b ON a.LastName=b.LastName AND a.FirstName=b.FirstName AND a.MiddleInit=b.MiddleInit AND a.Company=b.Company GROUP BY a.LastName, a.FirstName, a.MiddleInit, a.Company ORDER BY a.LastName, a.FirstName, a.MiddleInit, a.Company;

尝试使用 Pandas: 作为实验,我使用 CSV 加载了上面的 table,并编写了一个快速的 Python 脚本:

import pandas as pd
td1 = pd.read_csv('teamdata.csv',parse_dates=['LogDate'])
td2 = td1.groupby(['LastName','FirstName','MiddleInit','Company']).max().reset_index()

但这总是 returns “teamc” 作为团队,而不是对应于具有最新 LogDate 的行的团队:

In [1]: import pandas as pd

In [2]: td1 = pd.read_csv('teamdata.csv',parse_dates=['LogDate'])

In [3]: td2 = td1.groupby(['LastName','FirstName','MiddleInit','Company']).max().reset_index()

In [4]: td2
Out[4]:
  LastName FirstName MiddleInit Company   Team             LogDate
0    brady    thomas          c   compB  teamc 2015-10-02 03:15:00
1     lamb      mary          b   compA  teamc 2015-10-04 01:15:00
2    smith      john          d   compB  teamc 2015-10-05 09:15:00
3    smith    joseph          a   compA  teamc 2015-10-01 02:15:00

即使我为 groupby 使用自定义函数,我的理解是它只会作用于正在处理的列 (LogDate),而且我不知道如何引用该特定记录中的团队.任何想法都会受到赞赏,最好不要诉诸循环或多个 SQL 查询,但如果这是唯一可以做到的方法,我现在会采取任何措施。提前感谢您的帮助。

在 Postgres 中做您想做的最简单的方法是使用 distinct on:

select distinct on (lastname, firstname, middleinit, company) t.*
from table1 t
order by lastname, firstname, middleinit, company, logdate desc;

在 pandas 中,您可以使用 idxmax 获取每个组的最大值索引:

In [17]: df.loc[df.groupby(['LastName','FirstName','MiddleInit','Company'])['LogDate'].idxmax(), :]
Out[17]: 
   LastName FirstName MiddleInit Company   Team             LogDate
6     brady    thomas          c   compB  teama 2015-10-02 03:15:00
4      lamb      mary          b   compA  teamb 2015-10-04 01:15:00
10    smith      john          d   compB  teamb 2015-10-05 09:15:00
2     smith    joseph          a   compA  teamc 2015-10-01 02:15:00