2016-05-05 8 views
1

Ich habe einen Datenrahmen mit vielen Spalten, die Wertpapiere, und der Index mit der Tageszeit von 00:00 bis 23:55 (jede Zeile ist ein 5-Minuten-Intervall), und jede Zelle hat entweder eine 1 oder eine 0. Ich möchte eine Art von Boxplot plotten, die die Daten ähnlich wie ich hier gezeichnet haben:Plotten Sicherheit vs Zeit mit Python

Sketch of desired plot Aber ich bin verwirrt, da alles, was ich habe binäre Werte und kann sie nicht verwenden, wenn sie gegen die Zeit plotten. Ich bin auf die Verwendung von Pandas und Matplotlib beschränkt.

+0

Können Sie ein kleines Beispiel dafür erstellen, wie der Datenrahmen aussieht? Ich glaube ich habe was du sagst aber nur um sicher zu sein. – Grr

+0

Hier ein Bild zu einem Beispiel: https://drive.google.com/file/d/0B4RoYkI5yaxbluuXdzNwaXBCTWs/view?usp=sharing – dgouder

+0

Hallo @dgouder. Ich glaube, dass Ihre Frage dieser http://stackoverflow.com/questions/36880103/creating-horizontal-bar-plot-with-time-series-data-in-python/36992409#36992409 ziemlich ähnlich ist. Können Sie uns einen Beispieldatensatz zur Verfügung stellen? –

Antwort

1

Eine Möglichkeit wäre die Verwendung des Links, den ich oben kommentiert habe, obwohl der ursprüngliche Datensatz anders ist. Das Verfahren besteht in assign numerischen Werten jede Spalte und die Nullen von NaN ändern, wie folgt:

import pandas as pd 
import matplotlib.pyplot as plt 
df = pd.read_csv("testdata.txt",parse_dates=0,index_col=0) 
df = df.applymap(lambda x:x if x else pd.np.nan) 
for n, col in enumerate(df.columns): df[col] = df[col]*n 
df.plot(lw=10,legend=False) 
plt.yticks(pd.np.arange(len(df.columns)), df.columns) 
plt.tight_layout() 
plt.show() 

das Ergebnis Datenrahmen ist:

     A B C D E 
time         
2016-05-05 00:00:00 0 NaN NaN NaN 4 
2016-05-05 00:05:00 0 NaN NaN 3.0 4 
2016-05-05 00:10:00 0 NaN NaN 3.0 4 
2016-05-05 00:15:00 0 NaN NaN 3.0 4 

und das Grundstück:

enter image description here

grüße.

0

Ich denke, was Sie verwenden könnten, ist das gebrochene Balkendiagramm in Matplotlib. Die Dokumentation ist here.

Hier ist eine einfache Version, die ich getestet habe: Leider konnte ich keinen Weg finden, um die Operationen durch Eigenkapital zu vektorisieren.

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

df = pd.DataFrame() 
df['qqq'] = [1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,1,0,0,0] 
df['dia'] = [0,0,1,1,0,1,0,1,1,1,0,0,0,1,1,0,0,1,1,1,1,1,1,1,1] 

ones = [] 
for col in df.columns: 
    one = df[df[col].diff() != 0][:][col] 
    one = one[one == 1] 
    ones.append(one) 

hranges = [] 
for col in df.columns: 
    diff = df[df[col].diff() != 0] 
    spread = pd.DataFrame(diff[col].index, columns=[col]) 
    spread = spread.set_value(len(spread), col, len(df[col].index)) 
    spread = spread.diff(periods=-1).fillna(spread[pd.isnull(spread.diff()) == True])*-1 
    spread = spread.drop(spread.index[-1]) 
    re_index = pd.DataFrame(df[df[col].diff() != 0][:][col].tolist()) 
    re_index = re_index[re_index[0] == 0] 
    hranges.append(spread.drop(re_index[re_index[0] == 0].index)) 
    hranges[j].columns = ['width'] 
    hranges[j]['hval'] = ones[j].index.tolist() 
    cols = hranges[j].columns 
    cols = cols[-1:] | cols [:-1] 
    hranges[j] = hranges[j][cols] 
    j += 1 

vals = [] 
for j in range(len(hranges)):  
    val = [(hranges[j].hval[i], hranges[j].width[i]) for i in hranges[j].index] 
    vals.append(val) 

fig, ax = plt.subplots() 
j = 0 
for col in df.columns: 
    ax.broken_barh(vals[j], ((j+1)*10,10)) 
    j += 1 
ax.set_yticks([((k+1) * 10) + 5 for k in range(j)]) 
ax.set_yticklabels(df.columns)  
plt.show() 

Das Ergebnis sieht wie folgt aus:

enter image description here

Offensichtlich hat Ihr Beispiel einen Zeitwert für die x-Achse haben würde, aber ich denke, Sie könnten das herauszufinden.