将min()与groupby一起使用时,保留其他列

Poi*_*XIV 53 python aggregate pandas pandas-groupby

我正在使用groupbypandas数据帧删除所有没有特定列的最小行.像这样的东西:

df1 = df.groupby("item", as_index=False)["diff"].min()
Run Code Online (Sandbox Code Playgroud)

但是,如果我有超过这两列,则其他列将被删除.我可以使用groupby保留这些列,还是我必须找到一种不同的方法来删除行?

我的数据如下:

    item    diff   otherstuff
   0   1       2            1
   1   1       1            2
   2   1       3            7
   3   2      -1            0
   4   2       1            3
   5   2       4            9
   6   2      -6            2
   7   3       0            0
   8   3       2            9
Run Code Online (Sandbox Code Playgroud)

并应该最终像:

    item   diff  otherstuff
   0   1      1           2
   1   2     -6           2
   2   3      0           0
Run Code Online (Sandbox Code Playgroud)

但我得到的是:

    item   diff
   0   1      1           
   1   2     -6           
   2   3      0                 
Run Code Online (Sandbox Code Playgroud)

我一直在查看文档,找不到任何东西.我试过了:

df1 = df.groupby(["item", "otherstuff"], as_index=false)["diff"].min()

df1 = df.groupby("item", as_index=false)["diff"].min()["otherstuff"]

df1 = df.groupby("item", as_index=false)["otherstuff", "diff"].min()
Run Code Online (Sandbox Code Playgroud)

但是没有一个工作(用最后一个实现了语法在创建组之后聚合的意义).

DSM*_*DSM 95

方法#1:用于idxmin()获取最小元素的索引diff,然后选择:

>>> df.loc[df.groupby("item")["diff"].idxmin()]
   item  diff  otherstuff
1     1     1           2
6     2    -6           2
7     3     0           0

[3 rows x 3 columns]
Run Code Online (Sandbox Code Playgroud)

方法#2:排序diff依次,然后取每组中的第一个元素item:

>>> df.sort_values("diff").groupby("item", as_index=False).first()
   item  diff  otherstuff
0     1     1           2
1     2    -6           2
2     3     0           0

[3 rows x 3 columns]
Run Code Online (Sandbox Code Playgroud)

请注意,即使行内容相同,结果索引也不同.

  • 现在改为.sort_values ...对吗? (4认同)
  • 谢谢你!我发现第一个很慢而且不正确,但第二个很快,而且完全符合我的要求。我同时使用了多个索引,这可能把事情搞砸了。 (3认同)
  • 第一种返回所有“ NaN”,但是第二种方法有效。谢谢! (2认同)

jez*_*ael 9

你可以用DataFrame.sort_valuesDataFrame.drop_duplicates

df = df.sort_values(by='diff').drop_duplicates(subset='item')
print (df)
   item  diff  otherstuff
6     2    -6           2
7     3     0           0
1     1     1           2
Run Code Online (Sandbox Code Playgroud)

如果每个组可能的多个最小值和希望所有分列使用boolean indexingtransform每团最少值:

print (df)
   item  diff  otherstuff
0     1     2           1
1     1     1           2 <-multiple min
2     1     1           7 <-multiple min
3     2    -1           0
4     2     1           3
5     2     4           9
6     2    -6           2
7     3     0           0
8     3     2           9

print (df.groupby("item")["diff"].transform('min'))
0    1
1    1
2    1
3   -6
4   -6
5   -6
6   -6
7    0
8    0
Name: diff, dtype: int64

df = df[df.groupby("item")["diff"].transform('min') == df['diff']]
print (df)
   item  diff  otherstuff
1     1     1           2
2     1     1           7
6     2    -6           2
7     3     0           0
Run Code Online (Sandbox Code Playgroud)