{"id":570516,"date":"2025-05-27T22:26:57","date_gmt":"2025-05-27T21:26:57","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=pycharm&#038;p=570516"},"modified":"2025-09-15T09:41:08","modified_gmt":"2025-09-15T08:41:08","slug":"limpieza-de-datos-en-la-ciencia-de-datos","status":"publish","type":"pycharm","link":"https:\/\/blog.jetbrains.com\/es\/pycharm\/2025\/05\/limpieza-de-datos-en-la-ciencia-de-datos\/","title":{"rendered":"Limpieza de datos en la ciencia de datos"},"content":{"rendered":"<p>En esta serie de art\u00edculos del blog de Ciencia de datos, hemos hablado de <a href=\"https:\/\/blog.jetbrains.com\/pycharm\/2024\/10\/how-to-get-data\/\">d\u00f3nde obtener datos<\/a> y c\u00f3mo <a href=\"https:\/\/blog.jetbrains.com\/pycharm\/2024\/10\/data-exploration-with-pandas\/\" target=\"_blank\" rel=\"noreferrer noopener\">explorar esos datos utilizando pandas<\/a>, pero aunque esos datos son excelentes para el aprendizaje, no son similares a lo que denominaremos datos del <em>mundo real<\/em>. Los datos para el aprendizaje a menudo ya se han limpiado y pulido para que pueda aprender r\u00e1pidamente sin necesidad de aventurarse al mundo de la limpieza de datos, pero los datos del mundo real tienen problemas y est\u00e1n desordenados. Los datos del mundo real requieren una limpieza previa para poder ofrecernos datos \u00fatiles, y ese es el tema de este art\u00edculo del blog.\u00a0<\/p>\n<p>Los problemas con los datos pueden provenir del comportamiento de los propios datos, de la forma en que se recopilaron o incluso de la forma en que se introdujeron. Pueden ocurrir errores y descuidos en cada etapa del recorrido.\u00a0<\/p>\n<p>Aqu\u00ed hablamos espec\u00edficamente de limpieza de datos y no de transformaci\u00f3n de datos. La limpieza de datos garantiza que las conclusiones que extraiga de sus datos puedan generalizarse a la poblaci\u00f3n que defina. Por el contrario, la transformaci\u00f3n de datos implica tareas como la conversi\u00f3n de formatos de datos, la normalizaci\u00f3n de datos y la agregaci\u00f3n de datos.\u00a0<\/p>\n<h2 class=\"wp-block-heading\">\u00bfPor qu\u00e9 es importante la limpieza de datos?<\/h2>\n<p>Lo primero que debemos entender sobre los conjuntos de datos es lo que representan. La mayor\u00eda de los conjuntos de datos son una muestra que representa a una poblaci\u00f3n m\u00e1s amplia y, al trabajar con esta muestra, podr\u00e1 extrapolar (o <em>generalizar<\/em>) sus conclusiones a esta poblaci\u00f3n. Por ejemplo, hemos utilizado un <a href=\"https:\/\/www.kaggle.com\/datasets\/prevek18\/ames-housing-dataset\" target=\"_blank\" rel=\"noopener\">conjunto de datos<\/a> en los dos art\u00edculos anteriores del blog. Este conjunto de datos trata a grandes rasgos sobre la venta de casas, pero solo cubre una peque\u00f1a zona geogr\u00e1fica, un periodo de tiempo peque\u00f1o y, potencialmente, no todas las casas de esa zona y ese periodo; es una muestra de una poblaci\u00f3n mayor.\u00a0<\/p>\n<p>Sus datos deben ser una muestra representativa de la poblaci\u00f3n en general; por ejemplo, todas las ventas de viviendas en esa zona durante un periodo definido. Para asegurarnos de que nuestros datos son una muestra representativa de la poblaci\u00f3n en general, primero debemos definir los l\u00edmites de nuestra poblaci\u00f3n.\u00a0<\/p>\n<p>Como podr\u00e1 imaginar, suele resultar poco pr\u00e1ctico trabajar con toda la poblaci\u00f3n, salvo quiz\u00e1 con los datos del censo, por lo que deber\u00e1 decidir d\u00f3nde establecer los l\u00edmites. Estos l\u00edmites pueden ser geogr\u00e1ficos, demogr\u00e1ficos, temporales, de acci\u00f3n (como los transaccionales) o espec\u00edficos del sector. Existen numerosas formas de definir su poblaci\u00f3n, pero para generalizar sus datos de forma fiable, debe definirla antes de limpiar los datos.<\/p>\n<p>En resumen, si planea utilizar sus datos para cualquier tipo de an\u00e1lisis o <a href=\"https:\/\/blog.jetbrains.com\/pycharm\/2022\/06\/start-studying-machine-learning-with-pycharm\/\">aprendizaje autom\u00e1tico<\/a>, debe dedicar tiempo a limpiarlos para asegurarse de poder confiar en sus conclusiones y generalizarlas al <em>mundo real<\/em>. La limpieza de sus datos da como resultado an\u00e1lisis m\u00e1s precisos y, cuando se trata de aprendizaje autom\u00e1tico, tambi\u00e9n mejoras en el rendimiento.<\/p>\n<p>Si no limpia sus datos, se arriesga a problemas como no poder generalizar sus conclusiones a la poblaci\u00f3n en general de forma fiable, estad\u00edsticas de resumen inexactas y visualizaciones incorrectas. Si utiliza sus datos para entrenar modelos de aprendizaje autom\u00e1tico, esto tambi\u00e9n puede dar lugar a errores y predicciones inexactas.<\/p>\n<p align=\"center\"><a class=\"jb-download-button\" href=\"https:\/\/jb.gg\/m8p92h\" target=\"_blank\" rel=\"noopener\"><br \/>Pruebe PyCharm Professional gratis<br \/><\/a><\/p>\n<h2 class=\"wp-block-heading\">Ejemplos de limpieza de datos<\/h2>\n<p>Vamos a echar un vistazo a cinco tareas que puede utilizar para limpiar sus datos. No se trata de una lista exhaustiva, pero es un buen punto de partida cuando lleguen a sus manos datos del mundo real.<\/p>\n<h3 class=\"wp-block-heading\">Deduplicaci\u00f3n de datos<\/h3>\n<p>Los duplicados son un problema, porque pueden distorsionar sus datos. Imagine que est\u00e1 trazando un histograma en el que utiliza la frecuencia de los precios de venta. Si tiene duplicados del mismo valor, obtendr\u00e1 un histograma que tendr\u00e1 un patr\u00f3n inexacto a causa de los precios que est\u00e1n duplicados.\u00a0<\/p>\n<p>Como nota al margen, cuando hablamos de que la duplicaci\u00f3n es un problema en los conjuntos de datos, nos referimos a la duplicaci\u00f3n de filas enteras, cada una de las cuales es una \u00fanica observaci\u00f3n. Habr\u00e1 valores duplicados en las columnas, y eso es lo que esperamos. Solo estamos hablando de observaciones duplicadas.\u00a0<\/p>\n<p>Afortunadamente para nosotros, existe un <a href=\"https:\/\/pandas.pydata.org\/pandas-docs\/stable\/reference\/api\/pandas.DataFrame.duplicated.html\" target=\"_blank\" rel=\"noopener\">m\u00e9todo pandas<\/a> para detectar si hay duplicados en nuestros datos. Podemos utilizar el chat de <a href=\"https:\/\/www.jetbrains.com\/ai\/\" target=\"_blank\" rel=\"noopener\">JetBrains AI<\/a> si necesitamos un recordatorio con una petici\u00f3n como:<\/p>\n<p><em>Code to identify duplicate rows<\/em><\/p>\n<p>Este ser\u00eda el c\u00f3digo resultante:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">duplicate_rows = df[df.duplicated()]\nduplicate_rows<\/pre>\n<p>Este c\u00f3digo asume que su DataFrame se llama <code>df<\/code><em>, <\/em>as\u00ed que aseg\u00farese de cambiarlo por el nombre de su DataFrame si no es as\u00ed.\u00a0<\/p>\n<p>No hay ning\u00fan dato duplicado en el <a href=\"https:\/\/www.kaggle.com\/datasets\/prevek18\/ames-housing-dataset\" target=\"_blank\" rel=\"noopener\">conjunto de datos de Ames Housing<\/a> que hemos estado utilizando, pero si le apetece probarlo, eche un vistazo al <a href=\"https:\/\/www.kaggle.com\/datasets\/cites\/cites-wildlife-trade-database\" target=\"_blank\" rel=\"noopener\">conjunto de datos de la base de datos de comercio de fauna silvestre CITES<\/a> y vea si puede encontrar los duplicados utilizando el m\u00e9todo pandas anterior.<\/p>\n<p>Una vez que haya identificado los duplicados en su conjunto de datos, debe eliminarlos para evitar distorsionar los resultados. Para ello, puede obtener el c\u00f3digo con JetBrains AI de nuevo con una petici\u00f3n como:<\/p>\n<p><em>Code to drop duplicates from my dataframe\u00a0<\/em><\/p>\n<p>El c\u00f3digo resultante elimina los duplicados, restablece el \u00edndice de su DataFrame y, a continuaci\u00f3n, lo muestra como un nuevo DataFrame llamado df_cleaned:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">df_cleaned = df.drop_duplicates()\ndf_cleaned.reset_index(drop=True, inplace=True)\ndf_cleaned<\/pre>\n<p>Hay otras funciones de pandas que puede utilizar para una <a href=\"https:\/\/pandas.pydata.org\/pandas-docs\/stable\/reference\/api\/pandas.DataFrame.drop_duplicates.html\" target=\"_blank\" rel=\"noopener\">gesti\u00f3n de duplicados m\u00e1s avanzada<\/a>, pero esta es suficiente para empezar a deduplicar su conjunto de datos.<\/p>\n<h3 class=\"wp-block-heading\">Tratamiento de valores inveros\u00edmiles<\/h3>\n<p>Se pueden obtener valores inveros\u00edmiles cuando los datos se introducen incorrectamente o algo ha ido mal durante el proceso de recopilaci\u00f3n de datos. Para nuestro <a href=\"https:\/\/www.kaggle.com\/datasets\/prevek18\/ames-housing-dataset\" target=\"_blank\" rel=\"noopener\">conjunto de datos Ames Housing<\/a>, un valor inveros\u00edmil podr\u00eda ser un SalePrice negativo, o un valor num\u00e9rico en Roof Style.<\/p>\n<p>La detecci\u00f3n de valores inveros\u00edmiles en su conjunto de datos se basa en un enfoque amplio que incluye examinar sus <a href=\"https:\/\/blog.jetbrains.com\/pycharm\/2024\/10\/data-exploration-with-pandas\/#summary-statistics\">estad\u00edsticas resumidas<\/a>, comprobar las reglas de validaci\u00f3n de datos definidas por el recopilador para cada columna y anotar cualquier punto de datos que quede fuera de esta validaci\u00f3n, as\u00ed como usar visualizaciones para detectar patrones y cualquier cosa que parezca ser una anomal\u00eda.\u00a0<\/p>\n<p>Es importante ocuparse de los valores inveros\u00edmiles, ya que pueden a\u00f1adir ruido y causar problemas en su an\u00e1lisis. Sin embargo, la forma de tratarlos est\u00e1 en cierto modo abierta a la interpretaci\u00f3n. Si no tiene muchos valores inveros\u00edmiles en relaci\u00f3n con el tama\u00f1o de su conjunto de datos, puede eliminar los registros que los contengan. Por ejemplo, si ha identificado un valor inveros\u00edmil en la fila 214 de su conjunto de datos, puede utilizar la <a href=\"https:\/\/pandas.pydata.org\/pandas-docs\/stable\/reference\/api\/pandas.DataFrame.drop.html\" target=\"_blank\" rel=\"noopener\">funci\u00f3n drop de pandas<\/a> para eliminar esa fila de su conjunto de datos.\u00a0<\/p>\n<p>Una vez m\u00e1s, podemos hacer que JetBrains AI genere el c\u00f3digo que necesitamos con una petici\u00f3n como:\u00a0<\/p>\n<p><em>Code that drops index 214 from <\/em><em>#df_cleaned<\/em><\/p>\n<p>Tenga en cuenta que en los <a href=\"https:\/\/www.jetbrains.com\/help\/pycharm\/jupyter-notebook-support.html\" target=\"_blank\" rel=\"noopener\">notebooks de Jupyter de PyCharm<\/a> podemos poner el signo # antes de una palabra para indicar al JetBrains AI Assistant que estoamos proporcionando contexto adicional y, en este caso, que el DataFrame se llama <code>df_cleaned<\/code>.<\/p>\n<p>El c\u00f3digo resultante eliminar\u00e1 esa observaci\u00f3n de su DataFrame, restablecer\u00e1 el \u00edndice y lo mostrar\u00e1:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">df_cleaned = df_cleaned.drop(index=214)\ndf_cleaned.reset_index(drop=True, inplace=True)\ndf_cleaned<\/pre>\n<p>Otra estrategia popular para tratar los valores inveros\u00edmiles es imputarlos, lo que significa que se sustituye el valor por otro diferente y veros\u00edmil basado en una estrategia definida. Una de las estrategias m\u00e1s comunes es utilizar el valor mediano en lugar del valor inveros\u00edmil. Dado que la mediana no se ve afectada por los valores at\u00edpicos, los cient\u00edficos de datos suelen elegirla para este fin, pero igualmente, la media o el valor de la moda de sus datos podr\u00edan ser m\u00e1s apropiados en algunas situaciones.\u00a0<\/p>\n<p>Como alternativa, si tiene conocimientos sobre el conjunto de datos y sobre c\u00f3mo se recopilaron, puede sustituir el valor inveros\u00edmil por otro que tenga m\u00e1s sentido. Si participa en el proceso de recopilaci\u00f3n de datos o lo conoce, esta opci\u00f3n puede ser para usted.\u00a0<\/p>\n<p>La forma en que decida tratar los valores inveros\u00edmiles depender\u00e1 de su prevalencia en el conjunto de datos, de c\u00f3mo se hayan recogido los datos y de c\u00f3mo pretenda definir su poblaci\u00f3n, as\u00ed como de otros factores como sus conocimientos del \u00e1mbito.\u00a0<\/p>\n<h3 class=\"wp-block-heading\">Formateo de datos<\/h3>\n<p>A menudo puede detectar problemas de formato con sus <a href=\"https:\/\/blog.jetbrains.com\/pycharm\/2024\/10\/data-exploration-with-pandas\/#summary-statistics\">estad\u00edsticas de resumen<\/a> o con las primeras <a href=\"https:\/\/blog.jetbrains.com\/pycharm\/2024\/10\/data-exploration-with-pandas\/#graphs\">visualizaciones<\/a> que realice para hacerse una idea de la forma de sus datos. Algunos ejemplos de formato incoherente son los valores num\u00e9ricos que no se definen todos con el mismo decimal o las variaciones ortogr\u00e1ficas, como \u00abprimero\u00bb y \u00ab1\u00ba\u00bb. Un formateo incorrecto de los datos tambi\u00e9n puede afectar a la huella de memoria de sus datos.<\/p>\n<p>Cuando detecte problemas de formateo en su conjunto de datos, deber\u00e1 estandarizar los valores. Dependiendo del problema al que se enfrente, esto implica normalmente definir su propia norma y aplicar el cambio. De nuevo, la biblioteca pandas tiene algunas funciones \u00fatiles aqu\u00ed como la de <a href=\"https:\/\/pandas.pydata.org\/pandas-docs\/stable\/reference\/api\/pandas.DataFrame.round.html\" target=\"_blank\" rel=\"noopener\">redondear<\/a>. Si quisiera redondear la columna SalePrice a 2 decimales, podr\u00edamos pedir el c\u00f3digo a JetBrains AI:<\/p>\n<p><em>Code to round <\/em><em>#SalePrice<\/em><em> to two decimal places\u00a0<\/em><\/p>\n<p>El c\u00f3digo resultante realizar\u00e1 el redondeo y luego imprimir\u00e1 las 10 primeras filas para que pueda comprobarlo:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">df_cleaned['SalePrice'] = df_cleaned['SalePrice].round(2)\ndf_cleaned.head()<\/pre>\n<p>Otro ejemplo ser\u00eda el de una ortograf\u00eda incoherente: por ejemplo, una columna HouseStyle que tenga tanto &#8220;1Story&#8221; como &#8220;OneStory&#8221;, y usted sepa que significan lo mismo. Puede utilizar la siguiente petici\u00f3n para obtener el c\u00f3digo correspondiente:<\/p>\n<p><em>Code to change all instances of <\/em><em>#OneStory<\/em><em> to <\/em><em>#1Story<\/em><em> in <\/em><em>#HouseStyle<\/em><em>\u00a0<\/em><\/p>\n<p>El c\u00f3digo resultante hace exactamente eso: sustituye todas las instancias de \u00abOneStory\u00bb por \u00ab1Story\u00bb:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">df_cleaned[HouseStyle'] = df_cleaned['HouseStyle'].replace('OneStory', '1Story')<\/pre>\n<h3 class=\"wp-block-heading\">Abordar los valores at\u00edpicos<\/h3>\n<p>Los valores at\u00edpicos son muy comunes en los conjuntos de datos, pero la forma de abordarlos, si es que se abordan, depende mucho del contexto. Una de las formas m\u00e1s sencillas de detectar valores at\u00edpicos es con un diagrama de caja, que utiliza las bibliotecas <a href=\"https:\/\/seaborn.pydata.org\/generated\/seaborn.boxplot.html\" target=\"_blank\" rel=\"noopener\">seaborn<\/a> y <a href=\"https:\/\/matplotlib.org\/stable\/api\/_as_gen\/matplotlib.pyplot.figure.html\" target=\"_blank\" rel=\"noopener\">matplotlib<\/a>. Ya habl\u00e9 de los diagramas de caja en mi anterior art\u00edculo del blog sobre la <a href=\"https:\/\/blog.jetbrains.com\/pycharm\/2024\/10\/data-exploration-with-pandas\/\">exploraci\u00f3n de datos con pandas<\/a>, por si necesita un repaso r\u00e1pido.\u00a0<\/p>\n<p>Nos fijaremos en SalePrice en nuestro <a href=\"https:\/\/www.kaggle.com\/datasets\/prevek18\/ames-housing-dataset\" target=\"_blank\" rel=\"noopener\">conjunto de datos de Ames Housing<\/a> para este diagrama de caja. De nuevo, utilizar\u00e9 JetBrains IA para que genere el c\u00f3digo por m\u00ed con una petici\u00f3n como la siguiente:<\/p>\n<p><em>Code to create a box plot of <\/em><em>#SalePrice<\/em><em>\u00a0<\/em><\/p>\n<p>Aqu\u00ed est\u00e1 el c\u00f3digo resultante que debemos ejecutar:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import seaborn as sns\nimport matplotlib.pyplot as plt\n\n# Create a box plot for SalePrice\nplt.figure(figsize=(10, 6))\nsns.boxplot(x=df_cleaned['SalePrice'])\nplt.title('Box Plot of SalePrice')\nplt.xlabel('SalePrice')\nplt.show()<\/pre>\n<p>El diagrama de caja nos indica que tenemos un sesgo positivo porque la l\u00ednea mediana vertical dentro de la caja azul est\u00e1 a la izquierda del centro. Un sesgo positivo nos dice que tenemos m\u00e1s precios de la vivienda en el extremo m\u00e1s barato de la escala, lo que no es sorprendente. El diagrama de caja tambi\u00e9n nos indica visualmente que tenemos muchos valores at\u00edpicos en el lado derecho. Se trata de un peque\u00f1o n\u00famero de casas mucho m\u00e1s caras que el precio de la mediana.<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-536439\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image.png\" alt=\"\" width=\"1600\" height=\"1054\" \/><\/figure>\n<p>Puede aceptar estos valores at\u00edpicos ya que es bastante habitual que un peque\u00f1o n\u00famero de casas tenga un precio superior al de la mayor\u00eda. Sin embargo, todo esto depende de la poblaci\u00f3n a la que quiera poder generalizar y de las conclusiones que desee extraer de sus datos. Establecer l\u00edmites claros en torno a lo que forma parte de su poblaci\u00f3n y lo que no, le permitir\u00e1 tomar una decisi\u00f3n informada sobre si los valores at\u00edpicos en sus datos van a suponer un problema.\u00a0<\/p>\n<p>Por ejemplo, si su poblaci\u00f3n est\u00e1 formada por personas que no van a comprar mansiones caras, tal vez pueda eliminar estos valores at\u00edpicos. Si, por el contrario, la demograf\u00eda de su poblaci\u00f3n incluye a aquellos de los que cabe esperar razonablemente que compren estas casas caras, quiz\u00e1 quiera mantenerlas, ya que son relevantes para su poblaci\u00f3n.<\/p>\n<p>He hablado aqu\u00ed de los diagramas de caja como formas de detectar valores at\u00edpicos, pero otras opciones como los diagramas de dispersi\u00f3n y los histogramas pueden mostrarle r\u00e1pidamente si tiene valores at\u00edpicos en sus datos, para que pueda tomar una decisi\u00f3n informada sobre si necesita hacer algo al respecto.<\/p>\n<p>El tratamiento de los valores at\u00edpicos suele dividirse en dos categor\u00edas: eliminarlos o utilizar estad\u00edsticas de resumen menos propensas a los valores at\u00edpicos. En primer lugar, necesitamos saber exactamente de qu\u00e9 filas se trata.\u00a0<\/p>\n<p>Hasta ahora, solo hemos hablado de c\u00f3mo identificarlos visualmente. Hay diferentes formas de determinar qu\u00e9 observaciones son y no son valores at\u00edpicos. Un enfoque habitual es utilizar un m\u00e9todo denominado <em>puntuaci\u00f3n Z modificada<\/em>. Antes de ver c\u00f3mo y por qu\u00e9 se modifica, la puntuaci\u00f3n Z se define de la siguiente manera:<\/p>\n<p><em>Puntuaci\u00f3n Z =<\/em> (<em>valor del punto de datos<\/em> &#8211; <em>media<\/em>) \/ <em>desviaci\u00f3n t\u00edpica<\/em><\/p>\n<p>As\u00ed pues, la raz\u00f3n por la que modificamos la puntuaci\u00f3n Z para detectar valores at\u00edpicos es que tanto la media como la desviaci\u00f3n t\u00edpica son propensas a la influencia de valores at\u00edpicos seg\u00fan c\u00f3mo se calculan. La puntuaci\u00f3n Z modificada se define como:<\/p>\n<p><em>Puntuaci\u00f3n Z modificada =<\/em> (<em>valor del punto de datos<\/em> \u2013 <em>mediana<\/em>) \/ <em>mediana de las desviaciones<\/em> <em>absolutas<\/em><\/p>\n<p>Como aprendimos cuando hablamos de las <a href=\"https:\/\/blog.jetbrains.com\/pycharm\/2024\/10\/data-exploration-with-pandas\/#summary-statistics\">estad\u00edsticas de resumen<\/a>, la mediana no se ve afectada por los valores at\u00edpicos. La<em> mediana de las desviaciones absolutas<\/em> es el valor de la <em>mediana<\/em> de las desviaciones absolutas del conjunto de datos con respecto a la <em>mediana<\/em>. Por ejemplo, si su conjunto de datos contiene estos valores:<\/p>\n<p>1, 2, 2, 2,<strong> 3<\/strong>, 3, 3, 5,9<\/p>\n<p>Entonces su <em>mediana<\/em> es 3 como valor en el centro del conjunto de datos. Las desviaciones de su valor de mediana de 3 son las siguientes en el orden presentado anteriormente:<\/p>\n<p>2, 1, 1, 1, 0, 0, 0, 2, 5<\/p>\n<p>Si las ordenamos en orden ascendente obtenemos lo siguiente:<\/p>\n<p>0, 0, 0, 1, <strong>1<\/strong>, 1, 2, 2, 5<\/p>\n<p>Lo que significa que la <em>mediana de las desviaciones absolutas<\/em> en este ejemplo ser\u00eda 1.<\/p>\n<p>\u00bfC\u00f3mo calculamos la puntuaci\u00f3n Z modificada de nuestro conjunto de datos para SalePrice? Pid\u00e1mosle a JetBrains AI lo siguiente:<\/p>\n<p><em>Given:<\/em><\/p>\n<p><em>Modified Z-score = (data point value \u2013 median) \/ median absolute deviation<\/em><\/p>\n<p><em>Calculate the Modified Z-score for <\/em><em>#SalePrice<\/em><em>\u00a0<\/em><\/p>\n<p>El resultado es este c\u00f3digo:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import pandas as pd\nfrom scipy.stats import median_abs_deviation\n\n\n# Assuming 'data' is your DataFrame and it contains the 'SalePrice' column\n\n\n# Calculate the median for the SalePrice column\nmedian_sale_price = data['SalePrice'].median()\n\n\n# Calculate the Median Absolute Deviation (MAD) for the SalePrice column\nmad_sale_price = median_abs_deviation(data['SalePrice'], scale='normal')\n\n\n# Calculate the Modified Z-scores for the SalePrice column\ndata['Modified_Z_Score'] = (data['SalePrice'] - median_sale_price) \/ mad_sale_price\n\n\n# Display the first few rows with the Modified Z-scores\nprint(data[['SalePrice', 'Modified_Z_Score']].head())<\/pre>\n<p>Cuando instalamos los paquetes necesarios y ejecutamos este c\u00f3digo, podemos ver que ya hemos recorrido parte del camino, pero ahora tenemos que decidir qu\u00e9 es un valor at\u00edpico para nuestro SalePrice bas\u00e1ndonos en la puntuaci\u00f3n Z modificada. La concepci\u00f3n general aqu\u00ed es que un valor at\u00edpico es cualquier valor &gt;=3 o &lt;=-3. Sin embargo, conviene se\u00f1alar que, como la mayor\u00eda de las decisiones estad\u00edsticas, puede y debe adaptarse a su conjunto de datos. &lt;=-3 however, it\u2019s worth noting that like most statistical decisions, it can and should be tailored to your dataset.\u00a0<\/p>\n<p>Pasemos otra petici\u00f3n a JetBrains AI para que podamos adaptar a\u00fan m\u00e1s nuestro resultado:<\/p>\n<p><em>Just list those that have a <\/em><em>#Modified_Z_Score<\/em><em> of 3 or above or -3 or below\u00a0<\/em><\/p>\n<p>Voy a tomar este fragmento de c\u00f3digo y a sustituirlo por las filas pertinentes de arriba:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Filter the rows where the Modified Z-score is 3 or above, or -3 or below\noutliers = data[(data['Modified_Z_Score'] &gt;= 3) | (data['Modified_Z_Score'] &lt;= -3)]\n\n\n# Print all the filtered rows, showing their index and SalePrice\noutliers = (outliers[['SalePrice', 'Modified_Z_Score']])\noutliers<\/pre>\n<p>He modificado este c\u00f3digo para guardar los valores at\u00edpicos en un nuevo DataFrame llamado valores at\u00edpicos e imprimirlos para poder verlos.\u00a0<\/p>\n<p>Nuestro siguiente paso ser\u00eda eliminar estos valores at\u00edpicos de nuestro DataFrame. Una vez m\u00e1s podemos utilizar JetBrains AI para generar el c\u00f3digo con una petici\u00f3n como:<\/p>\n<p><em>Create a new dataframe without the outliers\u00a0<\/em><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">data_without_outliers = data.drop(index=outliers.index)\n\n\n# Display the new DataFrame without outliers\nprint(data_without_outliers)<\/pre>\n<p>Nuestro nuevo DataFrame, data_without_outliers, excluye aquellos valores en los que la variable SalePrice se considera un valor at\u00edpico.\u00a0<\/p>\n<p>Podemos actualizar nuestro c\u00f3digo de diagrama de caja para ver el nuevo DataFrame. Sigue mostrando nuestro sesgo positivo como cabr\u00eda esperar, pero se han eliminado los valores considerados at\u00edpicos:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import seaborn as sns\nimport matplotlib.pyplot as plt\n\n\n# Create a box plot for SalePrice\nplt.figure(figsize=(10, 6))\nsns.boxplot(x=data_without_outliers['SalePrice'])\nplt.title('Box Plot of SalePrice')\nplt.xlabel('SalePrice')\nplt.show()<\/pre>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-536450\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-1.png\" alt=\"\" width=\"1572\" height=\"1076\" \/><\/figure>\n<p>Antes de terminar aqu\u00ed, echemos un vistazo a cu\u00e1ntas observaciones se han eliminado de nuestro DataFrame como porcentaje porque las consideramos valores at\u00edpicos en funci\u00f3n de SalePrice.<\/p>\n<p>Podemos utilizar una petici\u00f3n como esta:<\/p>\n<p><em>Calculate the percentage of observations removed between #data and #data_without_outliers<\/em><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Calculate the number of observations in the original and filtered DataFrames\noriginal_count = len(data)\nfiltered_count = len(data_without_outliers)\n\n# Calculate the number of removed observations\nremoved_count = original_count - filtered_count\n\n# Calculate the percentage of observations removed\npercentage_removed = (removed_count \/ original_count) * 100\n\n# Display the percentage\nprint(f\"Percentage of observations removed: {percentage_removed:.2f}%\")<\/pre>\n<p>PyCharm nos indica que se han eliminado el 5,67\u00a0% de las observaciones.<\/p>\n<p>Como he dicho antes, si mantiene los valores at\u00edpicos, considere la posibilidad de utilizar valores de resumen menos propensos a verse afectados por los valores at\u00edpicos, como la <em>mediana<\/em> y el <em>rango intercuart\u00edlico<\/em>. Puede plantearse utilizar estas medidas para sacar conclusiones cuando trabaje con conjuntos de datos que sabe que contienen valores at\u00edpicos que no ha eliminado porque son relevantes para la poblaci\u00f3n que ha definido y las conclusiones que desea extraer.<\/p>\n<h3 class=\"wp-block-heading\">Valores omitidos<\/h3>\n<p>La forma m\u00e1s r\u00e1pida de detectar los valores que faltan en un conjunto de datos es con sus estad\u00edsticas de resumen. Como recordatorio, en su DataFrame, haga clic en <em>Show Column Statistics<\/em> en el lado derecho y luego seleccione <em>Compact<\/em>. Los valores que faltan en las columnas se muestran en rojo, como puede ver aqu\u00ed para \u00abLot Frontage\u00bb en nuestro <a href=\"https:\/\/www.kaggle.com\/datasets\/prevek18\/ames-housing-dataset\" target=\"_blank\" rel=\"noopener\">conjunto de datos de Ames Housing<\/a>:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/AD_4nXdeSNdJvl9sk5Z8QXEJCr5rhDMI5GTGmaRdqvkIufNS8QZNQi-1QwDF1LQgTS_e9vm0B-pSKa5o2aZnNZEmPiAzvoaOjvRxmOICDRzuM_0iWumPGH_UWyR07Q8xTrzIUnYvL7-j-3.png\" width=\"624\" height=\"123\" \/><\/p>\n<p>Hay tres tipos de omisi\u00f3n que debemos tener en cuenta para nuestros datos:<\/p>\n<ul>\n<li>Omisi\u00f3n completa al azar<\/li>\n<li>Omisi\u00f3n al azar<\/li>\n<li>Omisi\u00f3n no al azar<\/li>\n<\/ul>\n<h3 class=\"wp-block-heading\">Omisi\u00f3n completa al azar<\/h3>\n<p>Omisi\u00f3n completa al azar significa que el dato ha desaparecido totalmente por casualidad y que el hecho de que falte no tiene relaci\u00f3n con otras variables del conjunto de datos. Esto puede ocurrir cuando alguien olvida responder a una pregunta de la encuesta, por ejemplo.\u00a0<\/p>\n<p>Los datos omitidos completamente al azar son raros, pero tambi\u00e9n son de los m\u00e1s f\u00e1ciles de tratar. Si tiene un n\u00famero relativamente peque\u00f1o de observaciones omitidas completamente al azar, el enfoque m\u00e1s com\u00fan es eliminar esas observaciones, porque hacerlo no deber\u00eda afectar a la integridad de su conjunto de datos y, por tanto, a las conclusiones que espera extraer.\u00a0<\/p>\n<h3 class=\"wp-block-heading\">Omisi\u00f3n al azar<\/h3>\n<p>Omisi\u00f3n al azar no parece tener un patr\u00f3n, pero tiene un patr\u00f3n subyacente que podemos explicar a trav\u00e9s de otras variables que hemos medido. Por ejemplo, alguien no respondi\u00f3 a una pregunta de la encuesta debido a la forma en que se obtuvieron los datos.<\/p>\n<p>Si volvemos a considerar nuestro <a href=\"https:\/\/www.kaggle.com\/datasets\/prevek18\/ames-housing-dataset\" target=\"_blank\" rel=\"noopener\">conjunto de datos de Ames Housing<\/a>, quiz\u00e1 la variable \u00abLot Frontage\u00bb (fachada de la parcela) falte con m\u00e1s frecuencia en las casas que venden ciertas agencias inmobiliarias. En ese caso, esta omisi\u00f3n podr\u00eda deberse a pr\u00e1cticas incoherentes de introducci\u00f3n de datos por parte de algunas agencias. Si es cierto, el hecho de que falten datos de \u00abLot Frontage\u00bb est\u00e1 relacionado con la forma en que la agencia que vendi\u00f3 la propiedad recopil\u00f3 los datos, que son una caracter\u00edstica observada, no la fachada de la parcela en s\u00ed.\u00a0<\/p>\n<p>Cuando le falten datos al azar, querr\u00e1 entender por qu\u00e9 faltan esos datos, lo que a menudo implica indagar en c\u00f3mo se recopilaron los datos. Una vez que entienda por qu\u00e9 faltan los datos, podr\u00e1 elegir qu\u00e9 hacer. Uno de los enfoques m\u00e1s comunes para hacer frente a los valores omitidos al azar es imputar los valores. Ya hemos hablado de esto para los valores inveros\u00edmiles, pero tambi\u00e9n es una estrategia v\u00e1lida para los valores que faltan. Existen varias opciones entre las que podr\u00eda elegir en funci\u00f3n de la poblaci\u00f3n definida y de las conclusiones que desee extraer, incluido el uso de variables correlacionadas como el tama\u00f1o de la casa, el a\u00f1o de construcci\u00f3n y el precio de venta en este ejemplo. Si comprende el patr\u00f3n que hay detr\u00e1s de los datos que faltan, a menudo puede utilizar informaci\u00f3n contextual para imputar los valores, lo que garantiza que se conserven las relaciones entre los datos de su conjunto de datos.\u00a0\u00a0<\/p>\n<h3 class=\"wp-block-heading\">Omisi\u00f3n no al azar<\/h3>\n<p>Por \u00faltimo, la omisi\u00f3n no al azar se da cuando la probabilidad de que falten datos est\u00e1 relacionada con datos no observados. Eso significa que la omisi\u00f3n depende de los datos no observados.\u00a0<\/p>\n<p>Por \u00faltima vez, volvamos a nuestro <a href=\"https:\/\/www.kaggle.com\/datasets\/prevek18\/ames-housing-dataset\" target=\"_blank\" rel=\"noopener\">conjunto de datos de Ames Housing<\/a> y al hecho de que nos faltan datos en \u00abLot Frontage\u00bb (fachada de la parcela). Una situaci\u00f3n de datos omitidos no al azar es cuando los vendedores deciden deliberadamente no informar del dato sobre la fachada de la parcela si consideran que es <em>peque\u00f1a<\/em> y, por tanto, informar al respecto podr\u00eda reducir el precio de venta de su casa. Si la probabilidad de que falten datos de \u00abLot Frontage\u00bb depende del tama\u00f1o de la propia fachada (que no se observa), es menos probable que se notifiquen las fachadas de parcelas m\u00e1s peque\u00f1as, lo que significa que la omisi\u00f3n de datos est\u00e1 directamente relacionada con el valor que falta.<\/p>\n<h3 class=\"wp-block-heading\">Visualizar la omisi\u00f3n<\/h3>\n<p>Siempre que falten datos, hay que comprobar si existe un patr\u00f3n. Si tiene un patr\u00f3n, entonces tiene un problema que probablemente deber\u00e1 resolver antes de poder generalizar sus datos.\u00a0<\/p>\n<p>Una de las formas m\u00e1s sencillas de buscar patrones es con las visualizaciones de mapas de calor. Antes de entrar en el c\u00f3digo, vamos a excluir las variables que no tengan ninguna omisi\u00f3n. Podemos pedir a JetBrains AI este c\u00f3digo:<\/p>\n<p><em>Code to create a new dataframe that contains only columns with missingness\u00a0<\/em><\/p>\n<p>Este es nuestro c\u00f3digo:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Identify columns with any missing values\ncolumns_with_missing = data.columns[data.isnull().any()]\n\n# Create a new DataFrame with only columns that have missing values\ndata_with_missingness = data[columns_with_missing]\n\n# Display the new DataFrame\nprint(data_with_missingness)<\/pre>\n<p>Antes de ejecutar este c\u00f3digo, cambie la l\u00ednea final para que podamos disfrutar del bonito dise\u00f1o de DataFrames de PyCharm:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">data_with_missingness<\/pre>\n<p>Ahora es el momento de crear un mapa de calor; de nuevo le pediremos a JetBrains AI un c\u00f3digo como este:<\/p>\n<p><em>Create a heatmap of <\/em><em>#data_with_missingness<\/em><em> that is transposed<\/em><\/p>\n<p>Este ser\u00eda el c\u00f3digo resultante:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import seaborn as sns\nimport matplotlib.pyplot as plt\n\n\n# Transpose the data_with_missingness DataFrame\ntransposed_data = data_with_missingness.T\n\n\n# Create a heatmap to visualize missingness\nplt.figure(figsize=(12, 8))\nsns.heatmap(transposed_data.isnull(), cbar=False, yticklabels=True)\nplt.title('Missing Data Heatmap (Transposed)')\nplt.xlabel('Instances')\nplt.ylabel('Features')\nplt.tight_layout()\nplt.show()<\/pre>\n<p>Tenga en cuenta que he eliminado cmap=&#8217;viridis&#8217; de los argumentos del mapa de calor, ya que me resulta dif\u00edcil visualizarlo.\u00a0<\/p>\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-537110\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/image-24.png\" alt=\"\" width=\"1600\" height=\"1065\" \/><\/figure>\n<p>Este mapa de calor sugiere que podr\u00eda haber un patr\u00f3n de omisi\u00f3n porque faltan las mismas variables en varias filas. En un grupo, podemos ver que Bsmt Qual, Bsmt Cond, Bsmt Exposure, BsmtFin Type 1 y Bsmt Fin Type 2 faltan en las mismas observaciones. En otro grupo, podemos ver que Garage Type, Garage Yr Bit, Garage Finish, Garage Qual y Garage Cond faltan en las mismas observaciones.<\/p>\n<p>Todas estas variables est\u00e1n relacionadas con s\u00f3tanos y garajes, pero hay otras variables relacionadas con garajes o s\u00f3tanos que no faltan. Una posible explicaci\u00f3n es que se formularon preguntas diferentes sobre garajes y s\u00f3tanos en las distintas agencias inmobiliarias cuando se recopilaron los datos, y no todas registraron tantos detalles como los que figuran en el conjunto de datos. Estos escenarios son comunes con datos que no recoge usted mismo, y puede explorar c\u00f3mo se recopilaron los datos si necesita saber m\u00e1s sobre la falta de datos en su conjunto de datos.<\/p>\n<h2 class=\"wp-block-heading\">Buenas pr\u00e1cticas para la limpieza de datos<\/h2>\n<p>Como ya he mencionado, la definici\u00f3n de su poblaci\u00f3n ocupa un lugar destacado en la lista de las mejores pr\u00e1cticas para la limpieza de datos. Sepa qu\u00e9 desea conseguir y c\u00f3mo quiere generalizar sus datos antes de empezar a limpiarlos.\u00a0<\/p>\n<p>Debe asegurarse de que todos sus m\u00e9todos son reproducibles, porque la reproducibilidad tambi\u00e9n requiere datos limpios. Las situaciones que no son reproducibles pueden causar un impacto significativo m\u00e1s adelante. Por este motivo, le recomiendo que mantenga sus notebooks de Jupyter ordenados y secuenciales, y que aproveche las funciones de Markdown para documentar su toma de decisiones en cada paso, especialmente con la limpieza.\u00a0<\/p>\n<p>Al limpiar los datos, debe trabajar de forma incremental, modificando el DataFrame en lugar del archivo CSV o la base de datos originales, y asegur\u00e1ndose de hacerlo todo con un c\u00f3digo reproducible y bien documentado.<\/p>\n<h2 class=\"wp-block-heading\">Resumen<\/h2>\n<p>La limpieza de datos es un gran tema y puede plantear muchos retos. Cuanto mayor sea el conjunto de datos, m\u00e1s dif\u00edcil ser\u00e1 el proceso de limpieza. Tendr\u00e1 que tener en cuenta a su poblaci\u00f3n para generalizar sus conclusiones de forma m\u00e1s amplia y, al mismo tiempo, equilibrar las compensaciones entre eliminar e imputar los valores que faltan y comprender por qu\u00e9 faltan esos datos en primer lugar.\u00a0<\/p>\n<p>Puede considerarse a s\u00ed mismo como la voz de los datos. Usted conoce el camino que han recorrido los datos y c\u00f3mo ha mantenido la integridad de estos en todas las etapas. Usted es la persona m\u00e1s indicada para documentar ese viaje y compartirlo con los dem\u00e1s.\u00a0<\/p>\n<p align=\"center\"><a class=\"jb-download-button\" href=\"https:\/\/jb.gg\/m8p92h\" target=\"_blank\" rel=\"noopener\"><br \/>Pruebe PyCharm Professional gratis<br \/><\/a><\/p>\n\n\n<p>A<em>rt\u00edculo original en ingl\u00e9s de:<\/em><br><\/p>\n\n\n    <div class=\"about-author \">\n        <div class=\"about-author__box\">\n            <div class=\"row\">\n                <div class=\"about-author__box-img\">\n                    <img decoding=\"async\" src=\"https:\/\/secure.gravatar.com\/avatar\/193dd3accbb2e467f1b46a7f38ea929d?s=200&#038;r=g\" width=\"200\" height=\"200\" alt=\"Helen Scott\" loading=\"lazy\"  class=\"avatar avatar-200 wp-user-avatar wp-user-avatar-200 photo avatar-default\">\n                <\/div>\n                <div class=\"about-author__box-text\">\n                                            <h4>Helen Scott<\/h4>\n                                                        <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n","protected":false},"author":1086,"featured_media":571246,"comment_status":"closed","ping_status":"closed","template":"","categories":[952],"tags":[],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/pycharm\/570516"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/pycharm"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/types\/pycharm"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/users\/1086"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/comments?post=570516"}],"version-history":[{"count":5,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/pycharm\/570516\/revisions"}],"predecessor-version":[{"id":601569,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/pycharm\/570516\/revisions\/601569"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/media\/571246"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/media?parent=570516"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/categories?post=570516"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/tags?post=570516"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/cross-post-tag?post=570516"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}