2015-12-04 2 views
0

У меня есть набор данных с выборкой по времени с по существу индексом с двумя столбцами (временная метка, идентификатор). Однако некоторые временные метки не имеют точки выборки для данного индекса.Как создать стек Matplotlib с разреженными данными?

Как сделать стек с Matplotlib для данных такого типа?

import pandas as pd 
import numpy as np 
import io 
import matplotlib.pyplot as plt 

df = pd.read_csv(io.StringIO(''' 
A,B,C 
1,1,0 
1,2,0 
1,3,0 
1,4,0 
2,1,.5 
2,2,.2 

2,4,.15 
3,1,.7 

3,3,.1 
3,4,.2 
'''.strip())) 

b = np.unique(df.B) 
plt.stackplot(np.unique(df.A), 
       [df[df.B==_b].C for _b in b], 
       labels=['B:{0}'.format(_b) for _b in b], 
) 
plt.xlabel('A') 
plt.ylabel('C') 
plt.legend(loc='upper left') 
plt.show() 

Когда я попробовать эту программу, Python отвечает:

TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe'' 

Когда я вручную заполнить недостающие точки данных (см пустые строки в строковый литерал), сюжет отлично работает.

enter image description here

Есть простой способ «вставить» нулевые записи недостающих данных выборки (как this question, но у меня есть две колонки функционируют как индексы, и я не знаю, как адаптировать решение к моему проблема) или иметь график Matplotlib с отверстиями?

ответ

1

Вы можете использовать df.pivot для массажа DataFrame в форме, поддающейся вызову DataFrame.plot(kind='area'). Например, если

In [46]: df 
Out[46]: 
    A B  C 
0 1 1 0.00 
1 1 2 0.00 
2 1 3 0.00 
3 1 4 0.00 
4 2 1 0.50 
5 2 2 0.20 
6 2 4 0.15 
7 3 1 0.70 
8 3 3 0.10 
9 3 4 0.20 

затем

In [47]: df.pivot(columns='B', index='A') 
Out[47]: 
    C     
B 1 2 3  4 
A      
1 0.0 0.0 0.0 0.00 
2 0.5 0.2 NaN 0.15 
3 0.7 NaN 0.1 0.20 

Обратите внимание, что df.pivot заполняет недостающие NaN значения для вас. Теперь, с DataFrame в этой форме,

result.plot(kind='area') 

производит нужный участок.


import pandas as pd 
import numpy as np 
import io 
import matplotlib.pyplot as plt 

try: 
    # for Python2 
    from cStringIO import StringIO 
except ImportError: 
    # for Python3 
    from io import StringIO 


df = pd.read_csv(StringIO(''' 
A,B,C 
1,1,0 
1,2,0 
1,3,0 
1,4,0 
2,1,.5 
2,2,.2 

2,4,.15 
3,1,.7 

3,3,.1 
3,4,.2 
'''.strip())) 


result = df.pivot(columns='B', index='A') 
result.columns = result.columns.droplevel(0) 
# Alternatively, the above two lines are equivalent to 
# result = df.set_index(['A','B'])['C'].unstack('B') 

ax = result.plot(kind='area') 
lines, labels = ax.get_legend_handles_labels() 
ax.set_ylabel('C') 
ax.legend(lines, ['B:{0}'.format(b) for b in result.columns], loc='best') 

plt.show() 

выходы enter image description here

Смежные вопросы