python - tutorial - Filtre filas de marcos de datos si el valor en la columna está en una lista de valores
graficar datos en python (7)
Rebanar datos con pandas
Dado un marco de datos como este:
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
Hay varias formas de seleccionar o dividir los datos.
Utilizando .isin
La más obvia es la característica .isin
. Puede crear una máscara que le proporcione una serie de afirmaciones True
/ False
, que se pueden aplicar a un marco de datos como este:
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
El enmascaramiento es la solución ad hoc al problema, pero no siempre funciona bien en términos de velocidad y memoria.
Con indexacion
Al establecer el índice en la columna STK_ID
, podemos usar el objeto de .loc
pandas .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
Esta es la forma más rápida de hacerlo, incluso si la indexación puede tardar un poco, ahorra tiempo si desea hacer varias consultas como esta.
Fusión de marcos de datos
Esto también se puede hacer mediante la fusión de marcos de datos. Esto se ajustaría más a un escenario en el que tiene mucha más información que en estos ejemplos.
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
Nota
Todos los métodos anteriores funcionan incluso si hay varias filas con el mismo ''STK_ID''
Tengo un rpt de DataFrame de los pandas de Python:
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
Puedo filtrar las filas cuyo id de stock es ''600809''
como este: 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
y quiero reunir todas las filas de algunas acciones, como [''600809'',''600141'',''600329'']
. Eso significa que quiero una sintaxis como esta:
stk_list = [''600809'',''600141'',''600329'']
rst = rpt[rpt[''STK_ID''] in stk_list] # this does not works in pandas
Dado que los pandas no aceptan el comando anterior, ¿cómo lograr el objetivo?
Puede utilizar la query
, es decir:
b = df.query(''a > 1 & a < 5'')
También puede query directamente su DataFrame para esta información.
rpt.query(''STK_ID in (600809,600141,600329)'')
O buscar de forma similar los rangos:
rpt.query(''60000 < STK_ID < 70000'')
También puede lograr resultados similares utilizando ''consulta'' y @:
p.ej:
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
También puedes usar rangos usando:
b = df[(df[''a''] > 1) & (df[''a''] < 5)]
Usa el método isin
. rpt[rpt[''STK_ID''].isin(stk_list)]
.
isin()
es ideal si tiene una lista de coincidencias exactas, pero si tiene una lista de coincidencias parciales o subcadenas para buscar, puede filtrar utilizando el método str.contains
y las expresiones regulares.
Por ejemplo, si queremos devolver un DataFrame donde todas las ID de stock que comienzan con ''600''
y luego van seguidas de tres dígitos:
>>> 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'' ...
... ... ...
Supongamos que ahora tenemos una lista de cadenas con las que queremos que ''STK_ID''
los valores en ''STK_ID''
, por ejemplo
endstrings = [''01$'', ''02$'', ''05$'']
Podemos unir estas cadenas con la expresión regular o el carácter |
y pase la cadena a str.contains
para filtrar el DataFrame:
>>> rpt[rpt[''STK_ID''].str.contains(''|''.join(endstrings)]
... STK_ID ...
... ''155905'' ...
... ''633101'' ...
... ''210302'' ...
... ... ...
Finalmente, contains
puede ignorar mayúsculas y minúsculas (estableciendo case=False
y case=False
), lo que le permite ser más general al especificar las cadenas que desea que coincidan.
Por ejemplo,
str.contains(''pandas'', case=False)
coincidiría con PANDAS
, PanDAs
, paNdAs123
, y así sucesivamente.