Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 基于groupby的数据帧过滤器_Python_Pandas_Pandas Groupby - Fatal编程技术网

Python 基于groupby的数据帧过滤器

Python 基于groupby的数据帧过滤器,python,pandas,pandas-groupby,Python,Pandas,Pandas Groupby,以下是我的简化示例: salesPerson customer measure timeStamp -------------------------------------- A 123 I 12:30 A 123 II 12:30 A 123 III 12:30 B 123

以下是我的简化示例:

      salesPerson customer measure timeStamp
      --------------------------------------
      A           123      I       12:30
      A           123      II      12:30
      A           123      III     12:30
      B           123      IV      12:35
      C           456      I       14:30
      C           456      II      14:30
      D           456      III     14:15
我想做的是,对数据帧进行归档,如果两个不同的销售人员Id具有相同的客户编号,则保留时间戳最早的销售人员的所有行。本例中的结果df为:

      salesPerson customer measure timeStamp
      --------------------------------------
      A           123      I       12:30
      A           123      II      12:30
      A           123      III     12:30
      D           456      III     14:15
做这件事的最佳/最具python风格的方式是什么?我曾想过使用pandas groupby.filter或groupby.transform,但坦率地说,我不知道如何准确地编写它们


额外的好处是将删除的行放在一个单独的已删除对象中。

这一行应该可以做到:

df[df['salesPerson'].isin(df.iloc[df.groupby(['customer'])['timeStamp'].idxmin(), 'salesPerson'])]
说明:

要确定我们要筛选的销售人员,首先按
customer
df
进行分组,并使用
idxmin
获得最小
时间戳的索引:

df.groupby(['customer'])['timeStamp'].idxmin()
然后,将这些索引值连同我们想要的列一起传递到
iloc
,以从
salesPerson
获取我们将用于筛选的值:

df.iloc[df.groupby(['customer'])['timeStamp'].idxmin(), 'salesPerson']
最后,将该结果传递给Series方法
isin
,并使用该方法索引到
df
。结果是:

0  A  123    I 2017-07-12 12:30:00
1  A  123   II 2017-07-12 12:30:00
2  A  123  III 2017-07-12 12:30:00
6  D  456  III 2017-07-12 14:15:00
要使用筛选出的行创建第二个数据帧,可以将索引从筛选出的df传递到原始df并排除这些行。因此,如果我们将上述结果分配给
df1
,我们可以通过以下方式创建一个互补的
df2

df2 = df[~df.index.isin(df1.index)]
结果:

3  B  123  IV 2017-07-12 12:35:00
4  C  456   I 2017-07-12 14:30:00
5  C  456  II 2017-07-12 14:30:00

这一行应该可以做到:

df[df['salesPerson'].isin(df.iloc[df.groupby(['customer'])['timeStamp'].idxmin(), 'salesPerson'])]
说明:

要确定我们要筛选的销售人员,首先按
customer
df
进行分组,并使用
idxmin
获得最小
时间戳的索引:

df.groupby(['customer'])['timeStamp'].idxmin()
然后,将这些索引值连同我们想要的列一起传递到
iloc
,以从
salesPerson
获取我们将用于筛选的值:

df.iloc[df.groupby(['customer'])['timeStamp'].idxmin(), 'salesPerson']
最后,将该结果传递给Series方法
isin
,并使用该方法索引到
df
。结果是:

0  A  123    I 2017-07-12 12:30:00
1  A  123   II 2017-07-12 12:30:00
2  A  123  III 2017-07-12 12:30:00
6  D  456  III 2017-07-12 14:15:00
要使用筛选出的行创建第二个数据帧,可以将索引从筛选出的df传递到原始df并排除这些行。因此,如果我们将上述结果分配给
df1
,我们可以通过以下方式创建一个互补的
df2

df2 = df[~df.index.isin(df1.index)]
结果:

3  B  123  IV 2017-07-12 12:35:00
4  C  456   I 2017-07-12 14:30:00
5  C  456  II 2017-07-12 14:30:00