Pandas график разброса данных с двухуровневым мультииндексом в качестве осей - PullRequest
1 голос
/ 10 июля 2020

У меня есть фрейм данных df с двухуровневым мультииндексом. Мне нужен график рассеяния с уровнем 0 по оси x и уровнем 1 по оси y и разбросанными точками для всех комбинаций, которые удовлетворяют условию, скажем, имеют ненулевое значение в столбце c 'col'.

import matplotlib.pyplot as plt
from itertools import product
import numpy as np

lengths = [3, 2]
df_index = pd.MultiIndex.from_product([list(product([-1,1], repeat=li)) for li in lengths], names=['level1', 'level2'])

df_cols = ['cols']
df = pd.DataFrame([[0.] * len(df_cols)] * len(df_index), index=df_index, columns=df_cols)
df['cols'] = np.random.randint(0, 2, size = len(df))
df

дает фрейм данных следующей формы

                       cols
level1       level2        
(-1, -1, -1) (-1, -1)     0
             (-1, 1)      0
             (1, -1)      0
             (1, 1)       0
(-1, -1, 1)  (-1, -1)     1
             (-1, 1)      0
             (1, -1)      1
             (1, 1)       1
(-1, 1, -1)  (-1, -1)     0
             (-1, 1)      0
             (1, -1)      0
             (1, 1)       0
(-1, 1, 1)   (-1, -1)     0
             (-1, 1)      0
             (1, -1)      1
             (1, 1)       0
(1, -1, -1)  (-1, -1)     0
             (-1, 1)      0
             (1, -1)      1
             (1, 1)       1
(1, -1, 1)   (-1, -1)     0
             (-1, 1)      1
             (1, -1)      1
             (1, 1)       0

...

Теперь мне нужен график рассеяния с индексом level1 по оси x и level2 индекс по оси Y таким образом, чтобы для каждого (x, y) с cols (x, y)! = 0 была точка.

1 Ответ

1 голос
/ 10 июля 2020

Давайте сначала создадим пример фрейма данных с двухуровневым мультииндексом:

import pandas as pd
import numpy as np
iterables = [[1, 2, 3, 4], [0,1, 2, 3, 4,5]]
my_multiindex=pd.MultiIndex.from_product(iterables, names=['first', 'second'])
series1 = pd.Series(np.random.randn(24), index=my_multiindex)
series2 = pd.Series(np.random.randn(24), index=my_multiindex)
df=pd.DataFrame({'col1':series1,'col2':series2})

Теперь давайте получим значения индекса, которые удовлетворяют заданному условию:

index_values=df[df.col1<0].index.values

Затем мы разделяем x и y координаты:

xs=[a[0] for a in index_values]
ys=[a[1] for a in index_values]

Затем мы строим:

from matplotlib import pyplot as plt
plt.scatter(xs,ys)

Если вы хотите, чтобы размер точек рассеивания отражал фактические значения, вы можете использовать:

column_values=abs(df[df.col1<0].col1.values)
plt.scatter(xs,ys,s=column_values*10)

Отредактируйте, чтобы отразить отредактированный вопрос :

Вам просто нужно преобразовать ваши xs и ys в строки. Я также использую большую цифру, чтобы метки осей не перекрывались:

plt.figure(figsize=(10,10))
plt.scatter([str(a) for a in xs],[str(a) for a in ys])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...