我有一个DataFrame ......
>>> df = pd.DataFrame({
... 'letters' : ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c'],
... 'is_min' : np.zeros(9),
... 'numbers' : np.random.randn(9)
... })
is_min letters numbers
0 0 a 0.322499
1 0 a -0.196617
2 0 a -1.194251
3 0 b 1.005323
4 0 b -0.186364
5 0 b -1.886273
6 0 c 0.014960
7 0 c -0.832713
8 0 c 0.689531
我想设置' is_min' col为1,如果'数字'是字母'列的最小值。我试过这个,觉得我很亲密......
>>> df.groupby('letters')['numbers'].transform('idxmin')
0 2
1 2
2 2
3 5
4 5
5 5
6 7
7 7
8 7
dtype: int64
我很难连接点以设置' is_min'到1。
答案 0 :(得分:4)
将行标签传递给loc
并设置列:
In [34]:
df.loc[df.groupby('letters')['numbers'].transform('idxmin'), 'is_min']=1
df
Out[34]:
is_min letters numbers
0 1 a -0.374751
1 0 a 1.663334
2 0 a -0.123599
3 1 b -2.156204
4 0 b 0.201493
5 0 b 1.639512
6 0 c -0.447271
7 0 c 0.017204
8 1 c -1.261621
所以,此处发生的是,通过调用loc
,我们只选择transform
方法返回的行,并根据需要将这些行设置为1
。< / p>
不确定是否重要,但您可以致电unique
,这样您就可以获得没有重复的行标签,这可能会更快:
df.loc[df.groupby('letters')['numbers'].transform('idxmin').unique(), 'is_min']=1
答案 1 :(得分:1)
如果'numbers'是'letters'列的最小值,我想将'is_min'col设置为1。
一种更直观的方法是计算每组letters
的最小值,然后使用分组.apply
分配is_min
:
def set_is_min(m):
df.loc[df.numbers == m, 'is_min'] = 1
mins = df.groupby('letters').numbers.min().apply(set_is_min)
在大型数据帧中,此方法实际上比使用transform快20%:
# timeit with 100'000 rows
# .apply on group minima
100 loops, best of 3: 16.7 ms per loop
# .transform
10 loops, best of 3: 21.9 ms per loop
我使用apply和transform运行了一些more benchmarks种方法。