Извините, если я упустил из виду подобную проблему, которая была решена в другом месте. Это посты, которые я изучал перед тем, как задавать этот вопрос:
Pandas Группировка данных в режиме групповой работы на основе условия
pandas групповой заменой на основе условия
Python pandas сгруппировать данные в соответствии с условием
проблема:
Для данного кадра данных
import pandas as pd
import numpy as np
df = pd.DataFrame({
'a': [1,2,2,3,3,4,5,5,6,6],
'b': np.random.rand(10),
'c': 10*[0],
})
со столбцом a
, в котором хранятся тождества, и столбцом b
со случайными значениями, я хочу пометить значения замены в столбце c
.
Если есть только одна запись для a
изменения не применяются.
Если есть две записи для a
, я хочу пометить запись в c
, для которой b
минимально:
a b c
0 1 0.472015 0 # <-- only one entry for a => nothing changes
1 2 0.553018 2 # <-- b is minimal => c gets value 2
2 2 0.770302 0
3 3 0.992023 0
4 3 0.119448 2 # <-- b is minimal => c gets value 2
подход:
Сочетание groupby
, agg
и .loc
g = df.groupby('a').agg({'b': [np.argmin, np.argmax]})
df.loc[g[g[('b', 'argmin')] != g[('b', 'argmax')]][('b', 'argmin')], 'c' ] = 2
Это работает, но кажется довольно окольным.
вопрос
есть ли менее неуклюжий способ go об этом?
спасибо
помощь очень ценится!
edit:
Группы имеют одного или двух членов. Если оба члена имеют одинаковое значение b
, ничего не должно происходить.
df = pd.DataFrame({
'a': [1,2,2,3,3,4,5,5,6,6],
'b': [1,1,2,1,2,1,1,1,2,1],
'c': 10*[0],
})
df.loc[df['b'].eq(df.groupby('a')['b'].transform('min')),'c']=2
out:
a b c
0 1 1 2
1 2 1 2
2 2 2 0
3 3 1 2
4 3 2 0
5 4 1 2
6 5 1 2
7 5 1 2
8 6 2 0
9 6 1 2
df.loc[df.index==df.groupby('a')['b'].transform('idxmin'),'c']=2
a b c
0 1 1 2 # <-- a has only one member, so this shouldn't be changed
1 2 1 2
2 2 2 0
3 3 1 2
4 3 2 0
5 4 1 2
6 5 1 2
7 5 1 0
8 6 2 0
9 6 1 2