Python( pandas): usuwanie duplikatów na podstawie dwóch kolumn utrzymujących wiersz z wartością maksymalną w innej kolumnie
Mam ramkę danych, która zawiera duplikaty wartości według dwóch kolumn (A i B):
A B C
1 2 1
1 2 4
2 7 1
3 4 0
3 4 8
Chcę usunąć duplikaty zachowując wiersz o maksymalnej wartości w kolumnie C. prowadziłoby to do:
A B C
1 2 4
2 7 1
3 4 8
Nie wiem, jak to zrobić. Czy powinienem użyć drop_duplicates()
, czegoś innego? 4 answers
Możesz to zrobić używając group by:
c_maxes = df.groupby(['A', 'B']).C.transform(max)
df = df.loc[df.C == c_maxes]
c_maxes
jest Series
z maksymalnych wartości C
w każdej grupie, ale która jest tej samej długości i z tym samym indeksem co df
. Jeśli nie użyłeś .transform
, drukowanie c_maxes
może być dobrym pomysłem, aby zobaczyć, jak to działa.
Innym podejściem używającym drop_duplicates
byłoby
df.sort('C').drop_duplicates(subset=['A', 'B'], take_last=True)
Nie wiem, który jest bardziej wydajny, ale myślę, że pierwsze podejście, ponieważ nie wymaga sortowania.
Edytuj:
Od pandas 0.18
w górę drugie rozwiązanie byłoby df.sort_values('C').drop_duplicates(subset=['A', 'B'], keep='last')
lub, alternatywnie, df.sort_values('C', ascending=False).drop_duplicates(subset=['A', 'B'])
. W każdym razie rozwiązanie groupby
wydaje się być znacznie bardziej wydajne:
%timeit -n 10 df.loc[df.groupby(['A', 'B']).C.max == df.C]
10 loops, best of 3: 25.7 ms per loop
%timeit -n 10 df.sort_values('C').drop_duplicates(subset=['A', 'B'], keep='last')
10 loops, best of 3: 101 ms per loop
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-08 17:22:37
Myślę, że groupby powinno działać.
df.groupby(['A', 'B']).max()['C']
Jeśli potrzebujesz ramki danych z powrotem, możesz połączyć wywołanie Reset indeksu.
df.groupby(['A', 'B']).max()['C'].reset_index()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-19 11:39:42
Możesz to zrobić po prostu za pomocą funkcji pandas drop duplicates
df.drop_duplicates(['A','B'],keep= 'last')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-07 08:24:34
Możesz to zrobić z drop_duplicates
jak chciałeś
# initialisation
d = pd.DataFrame({'A' : [1,1,2,3,3], 'B' : [2,2,7,4,4], 'C' : [1,4,1,0,8]})
d = d.sort_values("C", ascending=False)
d = d.drop_duplicates(["A","B"])
Jeśli ważne jest, aby uzyskać tę samą kolejność
d = d.sort_index()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-05 13:47:41