data field bcorr
0 A cs1 0.8
1 A cs2 0.9
2 A cs3 0.7
3 A pq1 0.4
4 A pq2 0.6
5 A pq3 0.5
6 B cs1 0.8
7 B cs2 0.9
8 B cs3 0.7
9 B pq1 0.4
10 B pq2 0.6
11 B pq3 0.5
Dla wszystkich danych A
i B
w kolumnie data
oddziel pola cs
i pq
z kolumny field
, a następnie zagreguj, aby uzyskać 2 maksymalna wartość bcorr
.
Przykładowy wynik byłby taki:
data field bcorr
0 A cs1 0.8
1 A cs2 0.9
4 A pq2 0.6
5 A pq3 0.5
6 B cs1 0.8
7 B cs2 0.9
10 B pq2 0.6
11 B pq3 0.5
W tym celu jedną z opcji jest zrobienie tego podczas tworzenia listy rekordów, która oczywiście będzie miała dużą złożoność.
Po drugie, chcę to zrobić z ramką danych pandas, gdzie użyłem groupby
w kolumnie data
, a następnie zastosowałem startswith
, aby uzyskać źródło field
, a następnie zastosowałem max
4 odpowiedzi
Najpierw wyodrębnij wspólną część każdego pola (pierwsze litery), a następnie posortuj wartości (największe wartości idą w dół). Na koniec pogrupuj według kolumny data
i serii field
, a następnie zachowaj dwie ostatnie wartości (najwyższe):
field = df['field'].str.extract('([^\d]+)', expand=False)
out = df.sort_values('bcorr').groupby(['data', field]).tail(2).sort_index()
print(out)
# Output
data field bcorr
0 A cs1 0.8
1 A cs2 0.9
4 A pq2 0.6
5 A pq3 0.5
6 B cs1 0.8
7 B cs2 0.9
10 B pq2 0.6
11 B pq3 0.5
Jeśli pole ma tylko dwie stałe litery do określenia pola, możesz użyć df['field'].str[:2]
zamiast df['field'].str.extract(...)
.
Możesz groupby
w kolumnie pola daty i podciągu za pomocą str[:2]
, który przechwytuje znaki do drugiego i użyj head(2)
.
head
zwraca pierwsze n
wierszy, więc będziesz musiał wcześniej posortować dane.
df.sort_values(by=['data','bcorr'],ascending=False).groupby(['data',df.field.str[:2]]).head(2).sort_index()
data field bcorr
0 A cs1 0.8
1 A cs2 0.9
4 A pq2 0.6
5 A pq3 0.5
6 B cs1 0.8
7 B cs2 0.9
10 B pq2 0.6
11 B pq3 0.5
Podążając za powyższą logiką, używając tail(2)
i sortując dane na odwrót, otrzymujesz ten sam wynik:
df.sort_values(by=['data','bcorr']).groupby(['data',df.field.str[:2]]).tail(2).sort_index()
EDYTUJ Jeśli chcesz uogólnić, aby zezwolić na dowolną liczbę niecyfrowych znaków w kolumnie pola, możesz użyć str.replace
, aby zastąpić wszystkie znaki numeryczne pustymi w groupby
:
df.sort_values(by=['data','bcorr']).groupby(['data',df.field.str.replace(r"[0-9]",'')]).tail(2).sort_index()
Oto jeden sposób:
(i) Utwórz nową kolumnę field_name
z field
, wybierając pierwsze elementy i użyj groupby
na data
i field_name
i użyj nlargest
, aby znaleźć dwie największe wartości dla każdej grupy do stworzenia serii temp
(ii) Używając indeksu temp
utworzonego w (i), filtruj df
(iii) Przypisz temp
do kolumny bcorr
filtrowanej Dataframe z (ii)
temp = df.assign(field_name=df['field'].str[:2]).groupby(['data','field_name'])['bcorr'].nlargest(2).droplevel([0,1]).sort_index()
out = df.loc[temp.index]
out['bcorr'] = temp
Wynik:
data field bcorr
0 A cs1 0.8
1 A cs2 0.9
4 A pq2 0.6
5 A pq3 0.5
6 B cs1 0.8
7 B cs2 0.9
10 B pq2 0.6
11 B pq3 0.5
Wierzę, że to jest coś, co próbujesz osiągnąć
import pandas as pd
df = {'data': ['A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B'],
'fie': ['cs1', 'cs2', 'cs3', 'pq1', 'pq2', 'pq3', 'cs1', 'cs2', 'cs3', 'pq1', 'pq2', 'pq3'],
'bcorr': [0.8, 0.9, 0.7, 0.4, 0.6, 0.5, 0.8, 0.9, 0.7, 0.4, 0.6, 0.5]}
df = {'data': df['data'], 'fie_c': [x[:2] for x in df['fie']], 'fie_n': [x[2] for x in df['fie']],
'bcorr': df['bcorr']}
df = pd.DataFrame(data=df)
df = df.sort_values('bcorr', ascending=False).groupby(by=['data', 'fie_c']).head(2).sort_values('data')
df['fie'] = df[['fie_c', 'fie_n']].apply(lambda x: '{}{}'.format(x[0], x[1]), axis=1)
df = df.drop(columns=['fie_c', 'fie_n'])
df = df[['data', 'fie', 'bcorr']]
print(df)
Wynik
data fie bcorr
1 A cs2 0.9
0 A cs1 0.8
4 A pq2 0.6
5 A pq3 0.5
7 B cs2 0.9
6 B cs1 0.8
10 B pq2 0.6
11 B pq3 0.5
Zwróć uwagę, że kilka pierwszych linii może być bardziej przejrzystych, ale skupiłem się na linii
df = df.sort_values('bcorr', ascending=False).groupby(by=['data', 'fie_c']).head(2).sort_values('data')
Który wykonuje większość ważnej pracy.
Podobne pytania
Nowe pytania
python
Python to wielozadaniowy, wielozadaniowy język programowania dynamicznie typowany. Został zaprojektowany tak, aby był szybki do nauczenia się, zrozumienia i użycia oraz wymuszania czystej i jednolitej składni. Należy pamiętać, że Python 2 oficjalnie nie jest obsługiwany od 01-01-2020. Mimo to, w przypadku pytań Pythona specyficznych dla wersji, dodaj znacznik [python-2.7] lub [python-3.x]. Korzystając z wariantu Pythona (np. Jython, PyPy) lub biblioteki (np. Pandas i NumPy), należy umieścić go w tagach.
df.field.str[:2]
. nie zadziała, jeśli mamy pole zaczynające się odcs
,abc
.