Pandas数据框架中的最大值和最小值

3

我有一个 Pandas 数据框,如下所示:

+-----+---+---+--+--+
|     | A | B |  |  |
+-----+---+---+--+--+
| 288 | 1 | 4 |  |  |
+-----+---+---+--+--+
| 245 | 2 | 3 |  |  |
+-----+---+---+--+--+
| 543 | 3 | 6 |  |  |
+-----+---+---+--+--+
| 867 | 1 | 9 |  |  |
+-----+---+---+--+--+
| 345 | 2 | 7 |  |  |
+-----+---+---+--+--+
| 122 | 3 | 8 |  |  |
+-----+---+---+--+--+
| 233 | 1 | 1 |  |  |
+-----+---+---+--+--+
| 346 | 2 | 6 |  |  |
+-----+---+---+--+--+
| 765 | 3 | 3 |  |  |
+-----+---+---+--+--+

我想要做的是从'A'列中1到3的范围内获取'B'列的最大值和最小值。

例如:

loop on A in range 1 to 3:
       get max and min values from column 'B'
       max = 6
       min = 3
loop on the next range of A from 1 to 3:
       get max and min values from column 'B'
       max = 9
       min = 7           
loop on the next range of A from 1 to 3:
       get max and min values from column 'B'
       max = 6
       min = 1

并将最小值和最大值添加到列中,如下:

+-----+---+---+--+----+
|     | A | B |min|max|
+-----+---+---+--+----+
| 288 | 1 | 4 | 3 | 6 |
+-----+---+---+--+----+
| 245 | 2 | 3 |   |   |
+-----+---+---+--+----+
| 543 | 3 | 6 |   |   |
+-----+---+---+--+----+
| 867 | 1 | 9 | 7 | 9 |
+-----+---+---+--+----+
| 345 | 2 | 7 |   |   |
+-----+---+---+--+----+
| 122 | 3 | 8 |   |   |
+-----+---+---+--+----+
| 233 | 1 | 1 | 1 | 6 |
+-----+---+---+--+----+
| 346 | 2 | 6 |   |   |
+-----+---+---+--+----+
| 765 | 3 | 3 |   |   |
+-----+---+---+--+----+
2个回答

4

如果不需要空值:

g = df.groupby(np.arange(len(df.index)) // 3)
df['min'] = g.B.transform('min')
df['max'] = g.B.transform('max')
print (df)
     A  B  min  max
288  1  4    3    6
245  2  3    3    6
543  3  6    3    6
867  1  9    7    9
345  2  7    7    9
122  3  8    7    9
233  1  1    1    6
346  2  6    1    6
765  3  3    1    6

对于空值可以添加空格,但是这样一来,minmax列中的所有值也会被转换为字符串:

g = df.groupby(np.arange(len(df.index)) // 3)
df['min'] = g.B.transform('min')
df['max'] = g.B.transform('max')
df.loc[df.A != 1, ['min','max']] = ''
print (df)
     A  B min max
288  1  4   3   6
245  2  3        
543  3  6        
867  1  9   7   9
345  2  7        
122  3  8        
233  1  1   1   6
346  2  6        
765  3  3    

编辑1:

df['range']='range' + pd.Series(np.arange(len(df.index))//3 + 1, index=df.index).astype(str) 
g = df.groupby('range')
df['min'] = g.B.transform('min')
df['max'] = g.B.transform('max')
print (df)
     A  B   range  min  max
288  1  4  range1    3    6
245  2  3  range1    3    6
543  3  6  range1    3    6
867  1  9  range2    7    9
345  2  7  range2    7    9
122  3  8  range2    7    9
233  1  1  range3    1    6
346  2  6  range3    1    6
765  3  3  range3    1    6

另一个使用布尔掩码的cumsum解决方案:
df['range'] = 'range' + (df.A == 1).cumsum().astype(str)
g = df.groupby('range')
df['min'] = g.B.transform('min')
df['max'] = g.B.transform('max')
print (df)
     A  B   range  min  max
288  1  4  range1    3    6
245  2  3  range1    3    6
543  3  6  range1    3    6
867  1  9  range2    7    9
345  2  7  range2    7    9
122  3  8  range2    7    9
233  1  1  range3    1    6
346  2  6  range3    1    6
765  3  3  range3    1    6

我不需要空格,但我需要区分'A'列上的范围。我该如何添加另一列,比如“范围”列,并放置当前范围的值。对于从1到3的第一个范围,可以命名为“范围1”,而对于下一个范围可能是“范围2”? - magicsword
你能帮我检查一下答案吗?我正在用手机。 - piRSquared
df['range'] = 'range' + (np.arange(len(df.index)) // 3).astype(str) and then g = df.groupby('range') I am only on phone so unchecked. ` - jezrael
我遇到了这个错误:ufunc 'add' 没有包含与类型 dtype('<U32') dtype('<U32') dtype('<U32') 匹配的循环。 - magicsword
太好了,很高兴能帮助你。 - jezrael
显示剩余2条评论

2

通用解决方案

g = df.groupby(df.groupby('A').cumcount())
df['min'] = g.B.transform('min')
df['max'] = g.B.transform('max')
print (df)
     A  B  min  max
288  1  4    3    6
245  2  3    3    6
543  3  6    3    6
867  1  9    7    9
345  2  7    7    9
122  3  8    7    9
233  1  1    1    6
346  2  6    1    6
765  3  3    1    6

这也可以,但我需要添加另一列来跟踪范围。例如,添加“范围”列,然后对于从1到3的A上的第一个范围,在范围列中添加“范围1”,然后对于A上的下一个范围等等在范围列中添加“范围2”。 - magicsword

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接