Filtruj wiersze ramki danych, jeśli wartość w kolumnie znajduje się na ustawionej liście wartości [duplikat]
Mam Python pandas DataFrame rpt
:
rpt
<class 'pandas.core.frame.DataFrame'>
MultiIndex: 47518 entries, ('000002', '20120331') to ('603366', '20091231')
Data columns:
STK_ID 47518 non-null values
STK_Name 47518 non-null values
RPT_Date 47518 non-null values
sales 47518 non-null values
Mogę filtrować wiersze, których ID akcji to '600809'
w następujący sposób: rpt[rpt['STK_ID'] == '600809']
<class 'pandas.core.frame.DataFrame'>
MultiIndex: 25 entries, ('600809', '20120331') to ('600809', '20060331')
Data columns:
STK_ID 25 non-null values
STK_Name 25 non-null values
RPT_Date 25 non-null values
sales 25 non-null values
I chcę Zbierz wszystkie rzędy niektórych zapasów razem, takie jak ['600809','600141','600329']
. To znaczy, że chcę taką składnię:
stk_list = ['600809','600141','600329']
rst = rpt[rpt['STK_ID'] in stk_list] # this does not works in pandas
Ponieważ pandy nie akceptują powyższego polecenia, jak osiągnąć cel?
7 answers
Użyj metody isin
:
rpt[rpt['STK_ID'].isin(stk_list)]
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
2020-02-25 00:45:48
isin()
jest idealny, jeśli masz listę dokładnych dopasowań, ale jeśli masz listę częściowych dopasowań lub podłańcuchów do wyszukiwania, możesz filtrować za pomocą str.contains
metody i wyrażenia regularne.
Na przykład, jeśli chcemy zwrócić ramkę danych, w której wszystkie identyfikatory stock rozpoczynają się od '600'
, a następnie są poprzedzone dowolnymi trzema cyframi:
>>> rpt[rpt['STK_ID'].str.contains(r'^600[0-9]{3}$')] # ^ means start of string
... STK_ID ... # [0-9]{3} means any three digits
... '600809' ... # $ means end of string
... '600141' ...
... '600329' ...
... ... ...
Załóżmy, że teraz mamy listę łańcuchów, na których chcemy, aby wartości w 'STK_ID'
kończyły się, np.
endstrings = ['01$', '02$', '05$']
Możemy dołączyć te łańcuchy ze znakiem regex ' or ' |
i przekazują łańcuch do str.contains
, aby filtrować ramkę danych:
>>> rpt[rpt['STK_ID'].str.contains('|'.join(endstrings)]
... STK_ID ...
... '155905' ...
... '633101' ...
... '210302' ...
... ... ...
Wreszcie, contains
może ignorować wielkość liter (ustawiając case=False
), co pozwala na bardziej ogólne określenie łańcuchów, które chcesz dopasować.
Na przykład,
str.contains('pandas', case=False)
Pasuje PANDAS
, PanDAs
, paNdAs123
, i tak dalej.
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-04-12 18:29:27
Możesz również użyć zakresów używając:
b = df[(df['a'] > 1) & (df['a'] < 5)]
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
2013-10-10 12:26:29
Możesz również bezpośrednio zapytać swoją ramkę danych o te informacje.
rpt.query('STK_ID in (600809,600141,600329)')
Lub podobnie Szukaj zakresów:
rpt.query('60000 < STK_ID < 70000')
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-10-27 15:39:51
Wycinanie danych za pomocą pand
Dane takie jak:
RPT_Date STK_ID STK_Name sales
0 1980-01-01 0 Arthur 0
1 1980-01-02 1 Beate 4
2 1980-01-03 2 Cecil 2
3 1980-01-04 3 Dana 8
4 1980-01-05 4 Eric 4
5 1980-01-06 5 Fidel 5
6 1980-01-07 6 George 4
7 1980-01-08 7 Hans 7
8 1980-01-09 8 Ingrid 7
9 1980-01-10 9 Jones 4
Istnieje wiele sposobów wybierania lub krojenia danych.
Używanie .isin
Najbardziej oczywistą jest .isin
funkcja. Możesz stworzyć maskę, która daje Ci serię True
/False
poleceń, które można zastosować do ramki danych takiej jak ta:
mask = df['STK_ID'].isin([4, 2, 6])
mask
0 False
1 False
2 True
3 False
4 True
5 False
6 True
7 False
8 False
9 False
Name: STK_ID, dtype: bool
df[mask]
RPT_Date STK_ID STK_Name sales
2 1980-01-03 2 Cecil 2
4 1980-01-05 4 Eric 4
6 1980-01-07 6 George 4
Maskowanie jest doraźnym rozwiązaniem problemu, ale nie zawsze działa dobrze pod względem szybkości i pamięci.
Z indeksowanie
Ustawiając indeks na kolumnę STK_ID
, możemy użyć pandy wbudowanej w obiekt krojenia .loc
df.set_index('STK_ID', inplace=True)
RPT_Date STK_Name sales
STK_ID
0 1980-01-01 Arthur 0
1 1980-01-02 Beate 4
2 1980-01-03 Cecil 2
3 1980-01-04 Dana 8
4 1980-01-05 Eric 4
5 1980-01-06 Fidel 5
6 1980-01-07 George 4
7 1980-01-08 Hans 7
8 1980-01-09 Ingrid 7
9 1980-01-10 Jones 4
df.loc[[4, 2, 6]]
RPT_Date STK_Name sales
STK_ID
4 1980-01-05 Eric 4
2 1980-01-03 Cecil 2
6 1980-01-07 George 4
Jest to szybki sposób na zrobienie tego, nawet jeśli indeksowanie może zająć trochę czasu, oszczędza to czas, jeśli chcesz wykonać wiele takich zapytań.
Scalanie ramek danych
Można to również zrobić poprzez scalanie ramek danych. Pasowałoby to bardziej do scenariusza, w którym masz o wiele więcej danych niż w tych przykładach.
stkid_df = pd.DataFrame({"STK_ID": [4,2,6]})
df.merge(stkid_df, on='STK_ID')
STK_ID RPT_Date STK_Name sales
0 2 1980-01-03 Cecil 2
1 4 1980-01-05 Eric 4
2 6 1980-01-07 George 4
Uwaga
Wszystkie powyższe metody działają nawet jeśli istnieje wiele wierszy o tym samym 'STK_ID'
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
2020-06-20 09:12:55
Możesz również osiągnąć podobne wyniki za pomocą 'query' i@:
Eg:
df = pd.DataFrame({'A': [1, 2, 3], 'B': ['a', 'b', 'f']})
df = pd.DataFrame({'A' : [5,6,3,4], 'B' : [1,2,3, 5]})
list_of_values = [3,6]
result= df.query("A in @list_of_values")
result
A B
1 6 2
2 3 3
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-09-28 03:04:39
Możesz użyć query
, czyli:
b = df.query('a > 1 & a < 5')
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-04-26 20:09:12