Biorąc pod uwagę ramkę danych przedziałów („czas rozpoczęcia” i „czas zakończenia”), jaki byłby skuteczny sposób wygenerowania histogramu pokazującego dla każdego punktu czasowego T, ile przedziałów jest w nim „aktywnych”?
Kod do wygenerowania przykładowej ramki danych (przepraszam, jestem pewien, że jest lepszy sposób, aby to zrobić):
from random import randint
intervals = []
for i in range(50):
start = randint(0,50)
intervals.append({"start":start, "end":start+randint(0,50)})
intervals_df = pd.DataFrame(intervals)
Przykład:
Dla następującej ramki danych:
import pandas as pd
pd.DataFrame([{"start":2,"end":5},{"start":3,"end":8},{"start":9,"end":10},{"start":4,"end":5}])
Dopasowany wykres będzie podobny do:
Moją intuicją jest to, że przedziały czasowe należy jakoś przełamać, aby rozdzielić wartości, aby można je było grupować, ale jak?
Odpowiedzi:
3 dla odpowiedzi № 1Możesz użyć apply
aby wygenerować wartości dla każdego zakresu melt
przekształcić dane w długą formę.
In [113]: expanded = df.apply(lambda row: pd.Series(np.arange(row["start"], row["end"] + 1)), axis=1)
In [114]: expanded
Out[114]:
0 1 2 3 4 5
0 2 3 4 5 NaN NaN
1 3 4 5 6 7 8
2 9 10 NaN NaN NaN NaN
3 4 5 NaN NaN NaN NaN
In [115]: expanded = pd.melt(expanded)["value"].dropna()
In [116]: expanded
Out[116]:
0 2
1 3
2 9
3 4
4 3
5 4
6 10
7 5
8 4
9 5
12 5
13 6
17 7
21 8
Name: value, dtype: float64
Stamtąd możesz użyć wbudowanego wykresu histogramu lub innego rodzaju binowania.
In [117]: expanded.hist()
1 dla odpowiedzi nr 2
odpowiedź chrisba jest świetna, ale powód, dla którego tymają odstęp między 5 a 6, ponieważ domyślna liczba pojemników wynosi domyślnie 10. Oznacza to, że w twoim przypadku pojemniki są odległe o 0,8, więc różnica wynosi w rzeczywistości między 5,2 a 6.
Sposobem na przeciwdziałanie temu jest ręczne ustawienie liczby pojemników równej długości twoich danych:
nb_bins = int(max(expanded) - min(expanded))
expanded.hist(bins = nb_bins)
Wynik: 1