- Deprecated function: Use of "static" in callables is deprecated in Drupal\user\Entity\Role::postLoad() (line 172 of core/modules/user/src/Entity/Role.php).
Drupal\user\Entity\Role::postLoad(Object, Array) (Line: 423)
Drupal\Core\Entity\EntityStorageBase->postLoad(Array) (Line: 353)
Drupal\Core\Entity\EntityStorageBase->loadMultiple(Array) (Line: 16)
Drupal\user\RoleStorage->isPermissionInRoles('access site in maintenance mode', Array) (Line: 112)
Drupal\Core\Session\UserSession->hasPermission('access site in maintenance mode') (Line: 105)
Drupal\Core\Session\AccountProxy->hasPermission('access site in maintenance mode') (Line: 83)
Drupal\redirect\RedirectChecker->canRedirect(Object) (Line: 120)
Drupal\redirect\EventSubscriber\RedirectRequestSubscriber->onKernelRequestCheckRedirect(Object, 'kernel.request', Object)
call_user_func(Array, Object, 'kernel.request', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.request') (Line: 145)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '83eddec9-08a5-4293-9d9a-cf89bfa341a9') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '83eddec9-08a5-4293-9d9a-cf89bfa341a9') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '83eddec9-08a5-4293-9d9a-cf89bfa341a9') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '83eddec9-08a5-4293-9d9a-cf89bfa341a9') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '3db49ed7-5077-4a51-a4f2-13034f54151f') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '3db49ed7-5077-4a51-a4f2-13034f54151f') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '3db49ed7-5077-4a51-a4f2-13034f54151f') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '3db49ed7-5077-4a51-a4f2-13034f54151f') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'd277a2fb-93f0-4411-89cf-a7a565d21ef9') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'd277a2fb-93f0-4411-89cf-a7a565d21ef9') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'd277a2fb-93f0-4411-89cf-a7a565d21ef9') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'd277a2fb-93f0-4411-89cf-a7a565d21ef9') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'f3f4b67f-e1cd-4023-8fa2-90621d585b3c') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'f3f4b67f-e1cd-4023-8fa2-90621d585b3c') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'f3f4b67f-e1cd-4023-8fa2-90621d585b3c') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'f3f4b67f-e1cd-4023-8fa2-90621d585b3c') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '9217d23d-fb51-42ee-a026-12165f74fac8') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '9217d23d-fb51-42ee-a026-12165f74fac8') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '9217d23d-fb51-42ee-a026-12165f74fac8') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '9217d23d-fb51-42ee-a026-12165f74fac8') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '1b7b724c-92ff-46f4-99a6-03a6a5dc985e') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '1b7b724c-92ff-46f4-99a6-03a6a5dc985e') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '1b7b724c-92ff-46f4-99a6-03a6a5dc985e') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '1b7b724c-92ff-46f4-99a6-03a6a5dc985e') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'b9be1c24-1ed6-4be5-bb9a-2b68332a5df1') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'b9be1c24-1ed6-4be5-bb9a-2b68332a5df1') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'b9be1c24-1ed6-4be5-bb9a-2b68332a5df1') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'b9be1c24-1ed6-4be5-bb9a-2b68332a5df1') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '0b9be60b-3111-463a-81e6-e4c51454a398') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '0b9be60b-3111-463a-81e6-e4c51454a398') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '0b9be60b-3111-463a-81e6-e4c51454a398') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '0b9be60b-3111-463a-81e6-e4c51454a398') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'c173c7db-1801-4273-988f-ca9b474ffa0b') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'c173c7db-1801-4273-988f-ca9b474ffa0b') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'c173c7db-1801-4273-988f-ca9b474ffa0b') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'c173c7db-1801-4273-988f-ca9b474ffa0b') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('El objetivo en este escenario es, partiendo de un dataframe, generar bins (bloques) definidos por los valores que tome una de las características y, a continuación, dividir el dataframe según estos bins.
Veamos un ejemplo muy sencillo: Supongamos que estamos trabajando con el dataset <em>Iris</em> y queremos dividirlo en N grupos en función de los valores que tome la característica "<em>sepal_length</em>". Tendríamos que crear N bins basados en los valores de <em>sepal_length</em> y, a continuación, asignar cada registro del dataframe a uno de los bins.
Para llevar esto a la práctica vamos a trabajar con apenas 5 registros del mencionado dataset <em>Iris</em>, y vamos a crear solo 2 bins: el primero cubrirá desde el valor más bajo de <em>sepal_length</em> hasta un valor intermedio de dicha columna, y el segundo desde el valor intermedio hasta el valor más elevado.
Si los bins se generan con el mismo tamaño, ese valor intermedio sería -en nuestro caso- el valor medio. Es decir, si partimos de los valores 1, 1, 1 y 2, los dos bins serían [1, 1.5] y [1.5, 2] (olvidémonos por un momento de si el valor 1.5 pertenecería al primer o al segundo bin).
Empecemos, en primer lugar, cargando el dataset iris y quedándonos solo con los primeros 5 registros:
import numpy as np
import pandas as pd
import seaborn as sns
iris = sns.load_dataset("iris")
iris = iris.head()
iris.head()
Mostramos -para poder hacer una comprobación visual- los valores mínimo y máximo de la columna <em>sepal_length</em>:
print("min: ", min(iris.sepal_length))
print("max: ", max(iris.sepal_length))
Ahora vamos a crear los bins. Para ello utilizaremos la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html" target="_blank">numpy.linspace()</a>, función que nos permite crear un conjunto de números equiespaciados entre dos dados. En nuestro ejemplo, los valores extremos vendrían definidos por el valor mínimo y máximo que acabamos de calcular:
bins = np.linspace(iris.sepal_length.min(), iris.sepal_length.max(), 3)
bins
Es decir, el primer bin vendría definido por el intervalo [4.6, 4.85] y el segundo por el intervalo [4.85, 5.1]. La cuestión de si el valor intermedio pertenece a uno u otro bin dependerá de cómo asignemos los registros a cada uno de los bins. Una buena opción es utilizar la función <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>, que devuelve los índices de los bins a los que pertenece cada uno de los registros: Es decir, a esta función habría que pasar los valores a repartir en bins (la columna <em>sepal_length</em> en nuestro caso) y los bins (que hemos almacenado en la variable homónima), y devolvería una lista de índices, uno para cada registro, indicando a cuál de los bins pertenece cada uno. Hagamos una primera prueba:
i = np.digitize(iris.sepal_length, bins)
i
Vemos, sin embargo, que se han asignado los registros no a 2 bins, sino a 3. La respuesta a esto la encontramos en la documentación de <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html" target="_blank">numpy.digitize()</a>:
El menor valor (o el mayor, pues esto es configurable mediante el parámetro <em>right</em>) siempre va a tener un bin propio (pues los bins son cerrados o por la derecha o por la izquierda), que no es lo que queremos: queremos generar solo 2 bins, y que todos los registros se incluyan en estos bins.
La solución es evitar que los valores mínimo y máximo a partir de los que se generan los bins coincidan con los valores mínimo y máximo de los datos a repartir en bins. Por ejemplo:
alpha = 0.0001
bins = np.linspace(iris.sepal_length.min() - alpha, iris.sepal_length.max() + alpha, 3)
bins
Ahora ninguno de los valores a repartir en los bins va a coincidir con los valores usados para generar los bins, por lo que todos deberían caer <strong>dentro</strong> de los bins. Comprobémoslo:
i = np.digitize(iris.sepal_length, bins)
i
Efectivamente, todos los índices apuntan a los dos bins que queríamos crear. Podemos comprobar visualmente que el primer valor de la columna <em>sepal_length</em> (5.1) que antes se incluía en su propio bin por ser el valor máximo ahora pertenece al bin 2 (el bin formado por los valores mayores o iguales a 4.85 y menores que 5.1001).
Y ahora que hemos generado el índice del bin al que pertenece cada registro, podemos dividir el dataframe usando la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html" target="_blank">pandas.groupby()</a> para, por ejemplo, calcular el número de registros en cada bin:
iris.groupby(by = i).species.count()
O calcular el valor medio del ancho del sépalo en cada bin:
iris.groupby(by = i).sepal_width.mean()
Obsérvese que, en este caso, no estamos pasando al parámetro <em>by</em> el nombre de un campo (que es, probablemente, lo más frecuente) sino una lista de valores que pandas asocia a cada registro para determinar los grupos.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Return type of Drupal\google_analytics\Component\Render\GoogleAnalyticsJavaScriptSnippet::jsonSerialize() should either be compatible with JsonSerializable::jsonSerialize(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in include() (line 10 of modules/contrib/google_analytics/src/Component/Render/GoogleAnalyticsJavaScriptSnippet.php).
include('/var/www/vhosts/interactivechaos.ovh/httpdocs/modules/contrib/google_analytics/src/Component/Render/GoogleAnalyticsJavaScriptSnippet.php') (Line: 578)
Composer\Autoload\ClassLoader::Composer\Autoload\{closure}('/var/www/vhosts/interactivechaos.ovh/httpdocs/modules/contrib/google_analytics/src/Component/Render/GoogleAnalyticsJavaScriptSnippet.php') (Line: 432)
Composer\Autoload\ClassLoader->loadClass('Drupal\google_analytics\Component\Render\GoogleAnalyticsJavaScriptSnippet') (Line: 372)
google_analytics_page_attachments(Array) (Line: 313)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}(Object, 'google_analytics') (Line: 405)
Drupal\Core\Extension\ModuleHandler->invokeAllWith('page_attachments', Object) (Line: 310)
Drupal\Core\Render\MainContent\HtmlRenderer->invokePageAttachmentHooks(Array) (Line: 288)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Use of "static" in callables is deprecated in Drupal\user\Entity\Role::postLoad() (line 172 of core/modules/user/src/Entity/Role.php).
Drupal\user\Entity\Role::postLoad(Object, Array) (Line: 423)
Drupal\Core\Entity\EntityStorageBase->postLoad(Array) (Line: 353)
Drupal\Core\Entity\EntityStorageBase->loadMultiple() (Line: 126)
eu_cookie_compliance_page_attachments(Array) (Line: 313)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}(Object, 'eu_cookie_compliance') (Line: 405)
Drupal\Core\Extension\ModuleHandler->invokeAllWith('page_attachments', Object) (Line: 310)
Drupal\Core\Render\MainContent\HtmlRenderer->invokePageAttachmentHooks(Array) (Line: 288)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\views\ManyToOneHelper::$handler is deprecated in Drupal\views\ManyToOneHelper->__construct() (line 24 of core/modules/views/src/ManyToOneHelper.php).
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 51)
Drupal\views\Plugin\views\filter\ManyToOne->defineOptions() (Line: 117)
Drupal\taxonomy\Plugin\views\filter\TaxonomyIndexTid->defineOptions() (Line: 141)
Drupal\views\Plugin\views\PluginBase->init(Object, Object, Array) (Line: 104)
Drupal\views\Plugin\views\HandlerBase->init(Object, Object, Array) (Line: 95)
Drupal\views\Plugin\views\filter\FilterPluginBase->init(Object, Object, Array) (Line: 44)
Drupal\views\Plugin\views\filter\InOperator->init(Object, Object, Array) (Line: 36)
Drupal\views\Plugin\views\filter\ManyToOne->init(Object, Object, Array) (Line: 98)
Drupal\taxonomy\Plugin\views\filter\TaxonomyIndexTid->init(Object, Object, Array) (Line: 894)
Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('filter') (Line: 1045)
Drupal\views\ViewExecutable->_initHandler('filter', Array) (Line: 903)
Drupal\views\ViewExecutable->initHandlers() (Line: 2633)
Drupal\views\Plugin\views\display\DisplayPluginBase->viewExposedFormBlocks() (Line: 35)
Drupal\views\Plugin\Block\ViewsExposedFilterBlock->build() (Line: 171)
Drupal\block\BlockViewBuilder::preRender(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, 1) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, 1) (Line: 160)
Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 159)
Drupal\Core\Render\Renderer->renderPlain(Array) (Line: 175)
Drupal\Core\Render\Renderer->renderPlaceholder('', Array) (Line: 665)
Drupal\Core\Render\Renderer->replacePlaceholders(Array) (Line: 550)
Drupal\Core\Render\Renderer->doRender(Array, 1) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, 1) (Line: 148)
Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 147)
Drupal\Core\Render\Renderer->renderRoot(Array) (Line: 279)
Drupal\Core\Render\HtmlResponseAttachmentsProcessor->renderPlaceholders(Object) (Line: 71)
Drupal\big_pipe\Render\BigPipeResponseAttachmentsProcessor->processAttachments(Object) (Line: 45)
Drupal\Core\EventSubscriber\HtmlResponseSubscriber->onRespond(Object, 'kernel.response', Object)
call_user_func(Array, Object, 'kernel.response', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.response') (Line: 202)
Symfony\Component\HttpKernel\HttpKernel->filterResponse(Object, Object, 1) (Line: 190)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\views\ManyToOneHelper::$handler is deprecated in Drupal\views\ManyToOneHelper->__construct() (line 24 of core/modules/views/src/ManyToOneHelper.php).
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 51)
Drupal\views\Plugin\views\filter\ManyToOne->defineOptions() (Line: 117)
Drupal\taxonomy\Plugin\views\filter\TaxonomyIndexTid->defineOptions() (Line: 228)
Drupal\views\Plugin\views\PluginBase->unpackOptions(Array, Array) (Line: 144)
Drupal\views\Plugin\views\PluginBase->init(Object, Object, Array) (Line: 104)
Drupal\views\Plugin\views\HandlerBase->init(Object, Object, Array) (Line: 95)
Drupal\views\Plugin\views\filter\FilterPluginBase->init(Object, Object, Array) (Line: 44)
Drupal\views\Plugin\views\filter\InOperator->init(Object, Object, Array) (Line: 36)
Drupal\views\Plugin\views\filter\ManyToOne->init(Object, Object, Array) (Line: 98)
Drupal\taxonomy\Plugin\views\filter\TaxonomyIndexTid->init(Object, Object, Array) (Line: 894)
Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('filter') (Line: 1045)
Drupal\views\ViewExecutable->_initHandler('filter', Array) (Line: 903)
Drupal\views\ViewExecutable->initHandlers() (Line: 2633)
Drupal\views\Plugin\views\display\DisplayPluginBase->viewExposedFormBlocks() (Line: 35)
Drupal\views\Plugin\Block\ViewsExposedFilterBlock->build() (Line: 171)
Drupal\block\BlockViewBuilder::preRender(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, 1) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, 1) (Line: 160)
Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 159)
Drupal\Core\Render\Renderer->renderPlain(Array) (Line: 175)
Drupal\Core\Render\Renderer->renderPlaceholder('', Array) (Line: 665)
Drupal\Core\Render\Renderer->replacePlaceholders(Array) (Line: 550)
Drupal\Core\Render\Renderer->doRender(Array, 1) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, 1) (Line: 148)
Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 147)
Drupal\Core\Render\Renderer->renderRoot(Array) (Line: 279)
Drupal\Core\Render\HtmlResponseAttachmentsProcessor->renderPlaceholders(Object) (Line: 71)
Drupal\big_pipe\Render\BigPipeResponseAttachmentsProcessor->processAttachments(Object) (Line: 45)
Drupal\Core\EventSubscriber\HtmlResponseSubscriber->onRespond(Object, 'kernel.response', Object)
call_user_func(Array, Object, 'kernel.response', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.response') (Line: 202)
Symfony\Component\HttpKernel\HttpKernel->filterResponse(Object, Object, 1) (Line: 190)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\views\ManyToOneHelper::$handler is deprecated in Drupal\views\ManyToOneHelper->__construct() (line 24 of core/modules/views/src/ManyToOneHelper.php).
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 51)
Drupal\views\Plugin\views\filter\ManyToOne->defineOptions() (Line: 117)
Drupal\taxonomy\Plugin\views\filter\TaxonomyIndexTid->defineOptions() (Line: 228)
Drupal\views\Plugin\views\PluginBase->unpackOptions(Array, Array) (Line: 110)
Drupal\views\Plugin\views\HandlerBase->init(Object, Object, Array) (Line: 95)
Drupal\views\Plugin\views\filter\FilterPluginBase->init(Object, Object, Array) (Line: 44)
Drupal\views\Plugin\views\filter\InOperator->init(Object, Object, Array) (Line: 36)
Drupal\views\Plugin\views\filter\ManyToOne->init(Object, Object, Array) (Line: 98)
Drupal\taxonomy\Plugin\views\filter\TaxonomyIndexTid->init(Object, Object, Array) (Line: 894)
Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('filter') (Line: 1045)
Drupal\views\ViewExecutable->_initHandler('filter', Array) (Line: 903)
Drupal\views\ViewExecutable->initHandlers() (Line: 2633)
Drupal\views\Plugin\views\display\DisplayPluginBase->viewExposedFormBlocks() (Line: 35)
Drupal\views\Plugin\Block\ViewsExposedFilterBlock->build() (Line: 171)
Drupal\block\BlockViewBuilder::preRender(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, 1) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, 1) (Line: 160)
Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 159)
Drupal\Core\Render\Renderer->renderPlain(Array) (Line: 175)
Drupal\Core\Render\Renderer->renderPlaceholder('', Array) (Line: 665)
Drupal\Core\Render\Renderer->replacePlaceholders(Array) (Line: 550)
Drupal\Core\Render\Renderer->doRender(Array, 1) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, 1) (Line: 148)
Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 147)
Drupal\Core\Render\Renderer->renderRoot(Array) (Line: 279)
Drupal\Core\Render\HtmlResponseAttachmentsProcessor->renderPlaceholders(Object) (Line: 71)
Drupal\big_pipe\Render\BigPipeResponseAttachmentsProcessor->processAttachments(Object) (Line: 45)
Drupal\Core\EventSubscriber\HtmlResponseSubscriber->onRespond(Object, 'kernel.response', Object)
call_user_func(Array, Object, 'kernel.response', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.response') (Line: 202)
Symfony\Component\HttpKernel\HttpKernel->filterResponse(Object, Object, 1) (Line: 190)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\views\ManyToOneHelper::$handler is deprecated in Drupal\views\ManyToOneHelper->__construct() (line 24 of core/modules/views/src/ManyToOneHelper.php).
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 38)
Drupal\views\Plugin\views\filter\ManyToOne->init(Object, Object, Array) (Line: 98)
Drupal\taxonomy\Plugin\views\filter\TaxonomyIndexTid->init(Object, Object, Array) (Line: 894)
Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('filter') (Line: 1045)
Drupal\views\ViewExecutable->_initHandler('filter', Array) (Line: 903)
Drupal\views\ViewExecutable->initHandlers() (Line: 2633)
Drupal\views\Plugin\views\display\DisplayPluginBase->viewExposedFormBlocks() (Line: 35)
Drupal\views\Plugin\Block\ViewsExposedFilterBlock->build() (Line: 171)
Drupal\block\BlockViewBuilder::preRender(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, 1) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, 1) (Line: 160)
Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 159)
Drupal\Core\Render\Renderer->renderPlain(Array) (Line: 175)
Drupal\Core\Render\Renderer->renderPlaceholder('', Array) (Line: 665)
Drupal\Core\Render\Renderer->replacePlaceholders(Array) (Line: 550)
Drupal\Core\Render\Renderer->doRender(Array, 1) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, 1) (Line: 148)
Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 147)
Drupal\Core\Render\Renderer->renderRoot(Array) (Line: 279)
Drupal\Core\Render\HtmlResponseAttachmentsProcessor->renderPlaceholders(Object) (Line: 71)
Drupal\big_pipe\Render\BigPipeResponseAttachmentsProcessor->processAttachments(Object) (Line: 45)
Drupal\Core\EventSubscriber\HtmlResponseSubscriber->onRespond(Object, 'kernel.response', Object)
call_user_func(Array, Object, 'kernel.response', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.response') (Line: 202)
Symfony\Component\HttpKernel\HttpKernel->filterResponse(Object, Object, 1) (Line: 190)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'taxonomy_term') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 228)
Drupal\taxonomy\Plugin\views\filter\TaxonomyIndexTid->valueForm(Array, Object) (Line: 941)
Drupal\views\Plugin\views\filter\FilterPluginBase->buildExposedForm(Array, Object) (Line: 111)
Drupal\views\Form\ViewsExposedForm->buildForm(Array, Object)
call_user_func_array(Array, Array) (Line: 534)
Drupal\Core\Form\FormBuilder->retrieveForm('views_exposed_form', Object) (Line: 281)
Drupal\Core\Form\FormBuilder->buildForm('\Drupal\views\Form\ViewsExposedForm', Object) (Line: 134)
Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase->renderExposedForm(1) (Line: 2638)
Drupal\views\Plugin\views\display\DisplayPluginBase->viewExposedFormBlocks() (Line: 35)
Drupal\views\Plugin\Block\ViewsExposedFilterBlock->build() (Line: 171)
Drupal\block\BlockViewBuilder::preRender(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, 1) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, 1) (Line: 160)
Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 159)
Drupal\Core\Render\Renderer->renderPlain(Array) (Line: 175)
Drupal\Core\Render\Renderer->renderPlaceholder('', Array) (Line: 665)
Drupal\Core\Render\Renderer->replacePlaceholders(Array) (Line: 550)
Drupal\Core\Render\Renderer->doRender(Array, 1) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, 1) (Line: 148)
Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 147)
Drupal\Core\Render\Renderer->renderRoot(Array) (Line: 279)
Drupal\Core\Render\HtmlResponseAttachmentsProcessor->renderPlaceholders(Object) (Line: 71)
Drupal\big_pipe\Render\BigPipeResponseAttachmentsProcessor->processAttachments(Object) (Line: 45)
Drupal\Core\EventSubscriber\HtmlResponseSubscriber->onRespond(Object, 'kernel.response', Object)
call_user_func(Array, Object, 'kernel.response', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.response') (Line: 202)
Symfony\Component\HttpKernel\HttpKernel->filterResponse(Object, Object, 1) (Line: 190)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('taxonomy_term_access') (Line: 145)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 228)
Drupal\taxonomy\Plugin\views\filter\TaxonomyIndexTid->valueForm(Array, Object) (Line: 941)
Drupal\views\Plugin\views\filter\FilterPluginBase->buildExposedForm(Array, Object) (Line: 111)
Drupal\views\Form\ViewsExposedForm->buildForm(Array, Object)
call_user_func_array(Array, Array) (Line: 534)
Drupal\Core\Form\FormBuilder->retrieveForm('views_exposed_form', Object) (Line: 281)
Drupal\Core\Form\FormBuilder->buildForm('\Drupal\views\Form\ViewsExposedForm', Object) (Line: 134)
Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase->renderExposedForm(1) (Line: 2638)
Drupal\views\Plugin\views\display\DisplayPluginBase->viewExposedFormBlocks() (Line: 35)
Drupal\views\Plugin\Block\ViewsExposedFilterBlock->build() (Line: 171)
Drupal\block\BlockViewBuilder::preRender(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, 1) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, 1) (Line: 160)
Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 159)
Drupal\Core\Render\Renderer->renderPlain(Array) (Line: 175)
Drupal\Core\Render\Renderer->renderPlaceholder('', Array) (Line: 665)
Drupal\Core\Render\Renderer->replacePlaceholders(Array) (Line: 550)
Drupal\Core\Render\Renderer->doRender(Array, 1) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, 1) (Line: 148)
Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 147)
Drupal\Core\Render\Renderer->renderRoot(Array) (Line: 279)
Drupal\Core\Render\HtmlResponseAttachmentsProcessor->renderPlaceholders(Object) (Line: 71)
Drupal\big_pipe\Render\BigPipeResponseAttachmentsProcessor->processAttachments(Object) (Line: 45)
Drupal\Core\EventSubscriber\HtmlResponseSubscriber->onRespond(Object, 'kernel.response', Object)
call_user_func(Array, Object, 'kernel.response', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.response') (Line: 202)
Symfony\Component\HttpKernel\HttpKernel->filterResponse(Object, Object, 1) (Line: 190)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)