当另一个组合时,pandas在组中至少获得一列

Leg*_*ack 5 python pandas pandas-groupby

我有一个像这样的pandas数据框:

      c     y
0     9     0
1     8     0
2     3     1
3     6     2
4     1     3
5     2     3
6     5     3
7     4     4
8     0     4
9     7     4
Run Code Online (Sandbox Code Playgroud)

我想分组y并得到最小值和最大值,c以便我的新数据帧看起来像这样:

      c     y     min   max
0     9     0     8     9
1     8     0     8     9
2     3     1     3     3   
3     6     2     6     6 
4     1     3     1     5
5     2     3     1     5
6     5     3     1     5
7     4     4     0     7
8     0     4     0     7
9     7     4     0     7
Run Code Online (Sandbox Code Playgroud)

我尝试使用df['min'] = df.groupby(['y'])['c'].min()但是这给了我一些奇怪的结果.最初的175行填充在min列中,但随后所有其余的都进入NaN.是不是你应该如何使用groupby方法?

Zer*_*ero 8

选项1使用transform

In [13]: dfc = df.groupby('y')['c']

In [14]: df.assign(min=dfc.transform(min), max=dfc.transform(max))
Out[14]:
   c  y  max  min
0  9  0    9    8
1  8  0    9    8
2  3  1    3    3
3  6  2    6    6
4  1  3    5    1
5  2  3    5    1
6  5  3    5    1
7  4  4    7    0
8  0  4    7    0
9  7  4    7    0
Run Code Online (Sandbox Code Playgroud)

要么

In [15]: df['min' ] = dfc.transform('min')

In [16]: df['max' ] = dfc.transform('max')
Run Code Online (Sandbox Code Playgroud)

选项2使用join和agg

In [30]: df.join(df.groupby('y')['c'].agg(['min', 'max']), on='y')
Out[30]:
   c  y  min  max
0  9  0    8    9
1  8  0    8    9
2  3  1    3    3
3  6  2    6    6
4  1  3    1    5
5  2  3    1    5
6  5  3    1    5
7  4  4    0    7
8  0  4    0    7
9  7  4    0    7
Run Code Online (Sandbox Code Playgroud)

选项3使用merge和agg

In [28]: df.merge(df.groupby('y')['c'].agg(['min', 'max']), right_index=True, left_on='y')
Out[28]:
   c  y  min  max
0  9  0    8    9
1  8  0    8    9
2  3  1    3    3
3  6  2    6    6
4  1  3    1    5
5  2  3    1    5
6  5  3    1    5
7  4  4    0    7
8  0  4    0    7
9  7  4    0    7
Run Code Online (Sandbox Code Playgroud)

  • 使用分组管道 `df.groupby('y')['c'].pipe(lambda g: df.assign(min=g.transform('min'), max=g.transform('max') ))` (2认同)

piR*_*red 5

与 Numpy 恶作剧

n = df.y.max() + 1
omax = np.ones(n, df.c.values.dtype) * df.c.values.min()
omin = np.ones(n, df.c.values.dtype) * df.c.values.max()
np.maximum.at(omax, df.y.values, df.c.values)
np.minimum.at(omin, df.y.values, df.c.values)

df.assign(min=omin[df.y], max=omax[df.y])

   c  y  min  max
0  9  0    8    9
1  8  0    8    9
2  3  1    3    3
3  6  2    6    6
4  1  3    1    5
5  2  3    1    5
6  5  3    1    5
7  4  4    0    7
8  0  4    0    7
9  7  4    0    7
Run Code Online (Sandbox Code Playgroud)