У меня есть фреймворк pandas с 4 столбцами и несколькими тысячами строк. Все записи либо True, либо False. Назовем фрейм данных «df» и столбцы «c0», «c1», «c2» и «c3». Меня интересует, сколько строк имеет каждое из 2 ^ 4 = 16 возможных значений истинности, поэтому я делаю кросс-таблицу:
xt = pd.crosstab([df.c0,df.c1],[df.c2,df.c3])
print(xt)
Это отображает красивую таблицу ячеек 4x4, каждая из которых содержит количество строк, которые имеют эту комбинацию значений истинности. Более того, пространственное расположение этих 16 ячеек имеет для меня значение и полезно. ОК, все хорошо. Но как мне это построить?
В частности, я хотел бы создать пузырьковую диаграмму этих подсчетов кросс-таблиц, т.е. графическое представление данных кросс-таблицы в том же пространственном расположении, что и в таблице, но теперь замените каждое число на цветная капля (скажем, круг) площадью, пропорциональной количеству. Итак, это диаграмма рассеяния с четырьмя (c0, c1) значениями истинности по одной оси, четырьмя (c2, c3) значениями истинности по другой оси и регулярной сеткой 4x4 из кругов разного размера.
Я знаю, что могу создать пузырьковую диаграмму, передав данные о размере ключевому слову 's' функции разброса matplotlib, но я не могу найти простой способ сообщить пандам о создании диаграммы рассеяния, которая использует заголовки столбцов в качестве x-координат , заголовки строк в виде y-координат и значения данных в виде размеров пузырьков для диаграммы рассеяния. Мне повезло: я преобразовал фрейм данных в массив numpy и построил его, но затем я теряю структуру меток осей из кросс-таблицы. (Да, я мог бы просто перестроить метки галочки вручную, но я хотел бы иметь возможность алгоритмически воспроизвести эту задачу для других аналогичных наборов данных.)
РЕДАКТИРОВАТЬ: Вдохновленный ответом @piRSquared ниже, вот некоторые пояснения того, о чем я прошу. Этот код близок к тому, что я хочу, но оси на результирующем графике потеряли какую-либо информацию о многоуровневой структуре меток MultiIndex объекта кросс-таблицы.
import pandas as pd
import numpy as np
randomData=np.random.choice([True,False],size=(100, 4),p=[.6,.4])
df = pd.DataFrame(randomData, columns=['c0','c1','c2','c3'])
xt=pd.crosstab([df.c0,df.c1], [df.c2,df.c3])
x=np.array([range(4)]*4)
y=x.transpose()[::-1,:]
pl.scatter(x,y,s=np.array(xt)*10)
(ссылка на изображение графика, так как у меня недостаточно репутации для встраивания: диаграмма рассеяния с плохо помеченные оси.) В идеале метки осей должны иметь визуально выровненную структуру, полученную из базового MultiIndex объекта кросс-таблицы, вроде этого:
c2 False True
c3 False True False True
c0 c1
False False 0 8 4 9
True 3 2 4 10
True False 7 5 3 10
True 2 7 8 18
Или, возможно, что-то напоминающее то, что здесь выражают легенда и ось абсцисс:
xt.plot(kind='bar',stacked=True)
(Другая ссылка на изображение графика: график стека, который знает о многоиндексной природе его базового фрейма данных.)