pandas 如何选择每组平均值最低的条目

xa9qqrwz  于 2023-04-28  发布在  其他
关注(0)|答案(6)|浏览(124)

假设我有以下 Dataframe

df = pd.DataFrame([
    (2, 2, 'A', .5),
    (2, 2, 'A', .6),
    (2, 2, 'B', .75),
    (2, 2, 'B', .7),
    (2, 2, 'C', .6),

    (2, 3, 'A', .65),
    (2, 3, 'A', .6),
    (2, 3, 'B', .75),
    (2, 3, 'B', .7),
    (2, 3, 'C', .6)
], columns=['out_size', 'problem_size', 'algo', 'time'])

我也想

  • group by `[out_size ','problem_size ',' algo '],对于每个组
  • 计算每个algo出现的次数,然后
  • 选择/保持该组中具有最低平均时间的algo

结果

pd.DataFrame(
      [[2, 2, 'A', 0.55],
       [2, 3, 'C', 0.6]], columns=['out_size', 'problem_size', 'algo', 'time'])
oewdyzsn

oewdyzsn1#

您可以使用双groupby

cols = ['out_size', 'problem_size', 'algo']

out = (df
 .groupby(cols, as_index=False)['time'].mean()
 .sort_values(by='time')
 .groupby(cols[:-1], as_index=False).first()
)

稍微更有效的替代方案,不需要对值进行排序(但需要存储中间值):

cols = ['out_size', 'problem_size', 'algo']

out = df.groupby(cols)['time'].mean()
out = out.loc[out.groupby(cols[:-1]).idxmin()].reset_index()

输出:

out_size  problem_size algo  time
0         2             2    A  0.55
1         2             3    C  0.60
xqkwcwgp

xqkwcwgp2#

您可以使用两个groupby来执行此操作:

group_cols = ["out_size", "problem_size", "algo"]
result = df.groupby(group_cols)["time"].mean().reset_index(drop=False)

计算每个组的平均时间。然后您可以按升序对时间进行排序:

result = result.sort_values("time", ascending=True)

然后再次分组(不包括列algo)并取每个组的第一个元素:

result = result.groupby(["out_size", "problem_size"])[["algo","time"]].first().reset_index(drop=False)
9q78igpj

9q78igpj3#

你可以这样做-首先groupby三列,然后按平均值进行agg,然后升序排序,然后你只想取组中的第一个,所以根据out_size和problem_size删除重复项,只保留第一个,这将保证你得到最低的平均值算法,因为它已经排序过了。

df.groupby(['out_size', 'problem_size', 'algo'],as_index=False).agg(
    {'time':'mean'}).sort_values(
    by='time',ignore_index=True).drop_duplicates(
    subset=['out_size', 'problem_size'], keep='first', ignore_index=True)

或者如果有更多的列都需要average agg,那么

agg_cols = ['time', #someother columns]
groupby_cols = df.columns.drop(agg_cols).tolist()
g = df.groupby(groupby_cols,as_index=False).agg('mean')
g.sort_values(by='time',ignore_index=True).drop_duplicates(
               subset=['out_size','problem_size'],ignore_index=True, keep='first')

输出:

out_size  problem_size algo  time
0         2             2    A  0.55
1         2             3    C  0.60
nr9pn0ug

nr9pn0ug4#

你可以在一行中通过-分组值,排序和分组再次:

df1 = df.groupby(['out_size', 'problem_size', 'algo'])['time'].mean().reset_index()
df1 = df1.sort_values(['out_size', 'problem_size', 'time'])
df1 = df1.groupby(['out_size', 'problem_size']).head(1)
df1

输出:

out_size  problem_size algo  time
      2             2      A     0.55
      2             3      C     0.60
bksxznpy

bksxznpy5#

cols = ['out_size', 'problem_size', 'algo']
out = df.groupby(cols)['time'].mean().unstack('algo').agg(['idxmin', 'min'], axis=1).reset_index()
out.rename(columns={'idxmin':'algo', 'min':'time'}, inplace=True)
print(out)

输出:

out_size  problem_size algo  time
0         2             2    A  0.55
1         2             3    C   0.6
ztmd8pv5

ztmd8pv56#

df.groupby(['out_size', 'problem_size']).apply(lambda dd:dd.groupby('algo')['time'].mean().nsmallest(1)).reset_index()

输出:

out_size  problem_size algo  time
0         2             2    A  0.55
1         2             3    C  0.60

相关问题