El buzón de correo de ingeniería
Episodio 4: ¡Pitones y pandas, Dios mío!

De vez en cuando, los ingenieros de sistemas nos topamos con preguntas interesantes que se salen un poco del uso típico de JMP . Estas aplicaciones suelen ser ingeniosas y a menudo demuestran que el uso de datos no se limita a resolver problemas técnicos o empresariales. Otras veces, las preguntas son simplemente problemas inesperados y desafiantes. Estos "desafíos inesperados" (como me gusta llamarlos) se presentan de muchas formas: problemas de programación, análisis interesantes, maneras de visualizar datos… ya se hacen una idea.
Hace tiempo que no escribo en la sección de correo, pero esta pregunta en particular me pareció que merecía ser respondida. La herramienta que utilicé para responderla no se menciona tanto como creo que debería. Así que esta es una oportunidad para ayudar a un colega de Nueva York y mostrarles algo interesante que quizás desconozcan de las capacidades de JMP.
La pregunta
Mike[JMP],
A menudo, necesito realizar agrupaciones donde necesito obtener, por ejemplo, el valor máximo de todo agrupado por alguna etiqueta, donde el equivalente en Python Pandas sería algo como:
df.groupby(['Algo', 'Otra cosa']).max()
Otra opción podría ser algo como pandas.nlargest con un groupby, donde querría decir los 5 elementos principales de un groupby.
Tras un par de minutos trasteando con la fórmula de una columna, me doy por vencido y exporto los datos para luego importarlos a JMP. La función Tabulate hace algo parecido, pero no siempre como yo quiero. Por eso, un documento sobre "Cómo usar JMP como si fuera Pandas" me sería de gran ayuda, y quizás también para JMP, dada la popularidad de Pandas.
Gracias,
Mella
Mi respuesta
¡Hola, Nick! Existe un truco que permite mayor flexibilidad en las fórmulas, similar a muchas de las funciones de Pandas. Consiste en indicarle a JMP por qué columnas se desea agrupar. Para ello, basta con hacer clic con el botón derecho en el nombre de la columna y seleccionar «Nueva columna de fórmula» > «Agrupar por».

Después de hacer eso, cualquier columna de fórmula que cree haciendo clic con el botón derecho en el nombre de la columna y usando Nueva columna de fórmula > … se agrupará según las columnas de agrupación que haya configurado.


Después de eso, solo queda filtrar o crear subconjuntos usando filtros de datos o filtros de datos locales. ¡Avísame si te sirve!
Mejor,
METRO
Pandas: ¿Adorables mustélidos o herramientas de análisis de datos?
Bien, para quienes no lo conozcan, Pandas no es un mustélido adorable con problemas de cromática. Pandas (generalmente abreviado como "pd" en los scripts de Python) es un "... lenguaje de programación de Python para la manipulación y el análisis de datos. En particular, ofrece estructuras de datos y operaciones para manipular tablas numéricas y series temporales [ fuente ]". Básicamente, cumple la función que las partes de organización y manipulación de datos de JMP (tablas de datos, menús de filas y columnas, etc.) desempeñan en el entorno de programación de Python. Por lo tanto, es bastante importante para los flujos de trabajo de análisis de datos en Python. Ahora bien, si buscas ejecutar Python desde dentro de JMP, este no es el artículo del blog para ti. Echa un vistazo a este documento técnico . Si buscas liberarte de realizar transformaciones de datos en la línea de comandos, sigue leyendo.
DataFrames y tablas de datos
¿Sigues aquí? ¡Genial! Bien, el resto de este artículo repasará algunos aspectos comunes de Pandas y su equivalente en JMP. No es una lista exhaustiva, ni mucho menos; su objetivo es orientarte al considerar ambos entornos.
Lo primero que quiero explicar es el "DataFrame". En Pandas, aquí es donde se almacena toda la información. Al igual que las tablas de datos en JMP, es esencialmente una colección de columnas de datos con un nombre (nombre de columna), etc. Se trabaja con columnas y filas (transformaciones, resúmenes, etc.), pero siempre se actúa sobre el DataFrame en su conjunto o sobre alguna parte del mismo.
En JMP, el contenedor de datos principal es la tabla de datos. Puedes manipular columnas y filas de la misma manera que en un DataFrame de Pandas. En ambos casos, puedes manejar valores faltantes en la tabla de datos. En JMP, se representan como una celda con un punto (para datos numéricos) o una celda en blanco (para datos de caracteres). Puedes transformar datos, resumirlos, etc. (más sobre esto más adelante). En ambos casos, cuanta más información le proporciones al software sobre los datos, menos trabajo manual tendrás que hacer, lo que me lleva a mi siguiente punto.
Propiedades de columna y tipos de datos
En lo que respecta a las propiedades de las columnas y los tipos de datos (dtypes en Pandas), JMP gana sin duda. Pandas hereda la mayor parte de su comprensión de los tipos de datos de otro paquete de Python llamado NumPy, lo cual es genial. NumPy es un código bastante robusto, pero es muy limitado en este aspecto. Maneja alrededor de ocho tipos de datos (ver la tabla a continuación [ fuente ]) con un soporte algo limitado para diferentes formatos (por ejemplo, se confunde bastante con las monedas sin ayuda).
| Tipo de datos |
Tipo de datos |
Escalar |
Formación |
Alias de cadena |
Documentación |
| fecha y hora con reconocimiento de zona horaria |
Tipo de fecha y hora TZD |
Marca de tiempo |
matrices.DatetimeArray |
'datetime64[ns, ]' |
Gestión de zonas horarias |
| Categórico |
CategóricoDtype |
(ninguno) |
Categórico |
'categoría' |
Datos categóricos |
| período (intervalos de tiempo) |
PeriodoDtype |
Período |
matrices.PeriodArray |
'período[ ]', 'Período[ ]' |
Representación de intervalos de tiempo |
| escaso |
TipoD disperso |
(ninguno) |
matrices.ArrayDisperso |
'Sparse', 'Sparse[int]', 'Sparse[float]' |
Estructuras de datos dispersas |
| intervalos |
Tipo de intervaloD |
Intervalo |
matrices.IntervalArray |
'intervalo', 'Intervalo', 'Intervalo[ ]', 'Intervalo[fecha y hora64[ns, ]]', 'Intervalo[timedelta64[ ]]' |
Índice de intervalo |
| entero anulable |
Tipo Int64D , … |
(ninguno) |
matrices.IntegerArray |
'Int8', 'Int16', 'Int32', 'Int64', 'UInt8', 'UInt16', 'UInt32', 'UInt64' |
Tipo de datos entero anulable |
Las propiedades de columna en JMP ocupan aproximadamente 43 páginas del libro "Using JMP" . Son considerablemente más extensas y reconocen eficazmente los tipos de datos durante su importación. Para un nuevo usuario de JMP, resulta especialmente interesante que las propiedades de columna se extiendan mucho más allá de los tipos de datos que utiliza Pandas. Puede gestionar una gran cantidad de metadatos que activan acciones en todo el software. Si bien es cierto que se pueden adjuntar atributos a un DataFrame de Pandas, dado que el DataFrame es solo un contenedor, es necesario implementar la compatibilidad con los atributos mediante código o esperar que el paquete que se esté utilizando ya la incluya. Todo esto ya está implementado en JMP.
Tabular, fórmulas de columna y agrupar por
La verdad es que los dos puntos anteriores no son tan importantes en el contexto de la pregunta que intentaba responder. Para nuestros propósitos, la tabla de datos/DataFrame es simplemente un contenedor para almacenar información. Las propiedades/tipos de las columnas pueden ser útiles para consideraciones analíticas, pero, de nuevo, eso no es importante para la pregunta que estamos abordando. La parte de Pandas que nos interesa se llama GroupBy. Se utiliza para segmentar y filtrar datos con el fin de prepararlos para otros análisis. Un ejemplo rápido usando la tabla de datos JMP Big Class para obtener la altura y el peso promedio de niños y niñas por edad podría verse así:
# Import Pandas
import pandas as pd
# Bring in the data
data = pd.read_csv("/Users/mike.anderson@jmp.com/Desktop/Big Class.csv")
# Put the data into a DataFrame
df = pd.DataFrame(data)
# Run the group by, get the means, and show the results
summ_df= df.groupby(['sex','age']).mean()
print(summ_df)
El resultado se verá algo así:
height weight
sex age
F 12 58.600000 100.200000
13 59.000000 95.333333
14 62.600000 96.600000
15 63.000000 102.000000
16 62.500000 113.500000
17 62.000000 116.000000
M 12 57.333333 97.000000
13 61.250000 94.250000
14 65.285714 103.857143
15 65.200000 110.800000
16 68.000000 128.000000
17 69.000000 153.000000
Normalmente, los usuarios de JMP recurren a Resumen o Tabulación como herramientas principales para estas operaciones de transformación de datos. Incluso podrían usar el Editor de fórmulas para crear una columna. Sin embargo, existe un recurso oculto en la tabla de datos (y en la lista de columnas de la plataforma ) que permite realizar prácticamente cualquier operación que se desee en Pandas y más. Este recurso consiste en hacer clic con el botón derecho en el nombre de una columna y seleccionar Nueva columna de fórmula. ¡Funciona en cualquier lugar donde haya una lista de columnas! A partir de ahí, se dispone de diversas opciones para realizar transformaciones, como combinar columnas, realizar sumas acumulativas en filas, etc. Eso, en sí mismo, si bien es útil, no es nada del otro mundo. Lo realmente interesante ocurre cuando activas la opción "Agrupar por" para una columna en JMP. Esto hará que cualquier columna de fórmula que crees reconozca automáticamente los niveles de una variable de agrupación. Piénsalo un momento: puedes crear una columna de fórmula en cualquier parte del software que se pueda estratificar según una columna de agrupación.
Veamos un ejemplo de lo que esto significa, tomado de otra pregunta que recibí recientemente:
Un ejemplo: ¡DOS PREGUNTAS POR EL PRECIO DE UNA!
Casi al mismo tiempo que recibí la pregunta inicial, otro cliente me preguntó cómo calcular una integral numérica (área bajo la curva o AUC) para una gran colección de muestras. Además, se mostraron dispuestos a proporcionarme un conjunto de datos de muestra que habían publicado previamente en un artículo de la revista Mutagénesis ambiental y molecular .
Resulta que lo que querían hacer se logró fácilmente usando indicadores de agrupación y columnas de función. Aquí está el procedimiento (puedes seguirlo usando los datos del sitio público de JMP 
Primero, grafiquemos los datos . Los detalles del estudio no son importantes para esta discusión, aunque su lectura es interesante . En resumen, se trata de una gran colección de sustancias químicas con diferentes concentraciones (Conc. (µM)) y una serie de respuestas genéticas. Para nuestro ejercicio, les interesa calcular el AUC para cada una de las respuestas genéticas. Aquí vemos un ejemplo en el Generador de gráficos con un selector de columnas:
El primer paso para calcular el AUC es configurar la agrupación. Haremos clic derecho en la columna "Sustancia química", seleccionaremos "Nueva columna de fórmula" y luego "Agrupar por". Repetiremos este proceso para la columna "Biomarcador". Es importante tener en cuenta el orden. Agruparemos primero por sustancia química y luego por biomarcador dentro de cada sustancia química. Después, solo queda usar la opción "Nueva columna de fórmula" en la tabla de datos para realizar el cálculo.

De ahora en adelante, he dividido cada paso en columnas individuales para mayor claridad. Y, si les interesa, estoy usando la suma de Riemann de la regla trapezoidal para los cálculos.
Bien, volvamos al cálculo. Lo primero que necesitamos es la distancia entre cada punto del eje x (el cambio en x punto por punto). Seleccionaremos la columna Conc (µm), haremos clic derecho en el título y seleccionaremos Nueva columna de fórmula > Fila > Diferencia. Ahora abrimos la fórmula en la nueva columna que creó JMP. Debería mostrar algo como esto:

Tenga en cuenta que JMP gestiona los cálculos entre filas y ha ajustado la fórmula para que se reinicie cuando detecta un nuevo tipo de sustancia química o biomarcador.
A continuación, necesitamos el valor promedio entre cada punto de datos y el anterior. Haga clic con el botón derecho en el encabezado de la columna y seleccione Nueva fórmula > Columna > Fila > Retraso. Abra la fórmula y modifíquela ligeramente para que calcule la diferencia entre filas y no solo el valor de la fila anterior. Esto se muestra en la siguiente captura de pantalla:

Esas dos columnas (las renombré dx y tú en la tabla de datos) deben multiplicarse para obtener el área de un segmento. Seleccione las dos columnas y haga clic derecho en el nombre de una de ellas. Seleccione Nueva columna de fórmula > Combinar > Producto. La nueva columna nos da el área aproximada bajo la curva entre cada punto de datos y el siguiente. Renombré esa columna como iAUC (AUC instantánea) en la tabla de datos.

El último paso consiste en sumar los valores de cada sección. Para ello, haga clic con el botón derecho en la columna iAUC y seleccione Nueva columna de fórmula > Fila > Suma acumulativa. Dado que seleccionamos las columnas de Agrupar por al inicio del ejercicio, el recuento se reinicia para cada muestra del conjunto de datos.

Desde aquí podríamos usar Tabulate o Summary para crear una tabla con los valores máximos para cada muestra (el área total aproximada bajo la curva). Aquí hay un ejemplo para un producto químico común:

Reflexiones finales
Y eso es todo. Puedes replicar fácilmente comportamientos de Pandas usando estructuras que existen en JMP. Solo recuerda usar la variable Group By y listo. No se requieren mustélidos, ni con problemas de cromática ni de ningún otro tipo.
Nota del editor:¿Has leído el?Otras entregas de nuestra serie "Buzón de correo de ingeniería"¿Vea cómo Mike ayuda a un usuario que estaba usando?JMPpara decidir si contratar un servicio de remoción de nieve y desarrollar visualizaciones únicas para programas educativos STEAM.