2015-07-10 80 views
7

我有一個熊貓數據框,每個觀察都有一個日期(作爲datetime [64]格式的一列條目)。這些日期分佈在大約5年的時間內。我想繪製所有觀測日期的核密度圖,以x軸標記年。如何繪製熊貓日期的核心密度圖?

我想通了如何創建相對於某些基準日期時間增量,然後創建的每個觀測和基準日期之間的小時/天/年數的密度圖:

df['relativeDate'].astype('timedelta64[D]').plot(kind='kde') 

但是,這並不是我想要的:如果我轉換爲年份 - 三角洲,那麼x軸是正確的,但我失去了年內的變化。但是如果我花時間或小時計算更小的時間單位,x軸標籤就更難解釋了。

在熊貓中進行這項工作最簡單的方法是什麼?

+0

看看KDE-情節seaborn:http://stanford.edu/~mwaskom/software/seaborn/generated/seaborn.kdeplot.html – Moritz

回答

3

通過@JohnE的回答啓發,另一種方法來轉換日期數值是使用.toordinal()

import pandas as pd 
import numpy as np 

# simulate some artificial data 
# =============================== 
np.random.seed(0) 
dates = pd.date_range('2010-01-01', periods=31, freq='D') 
df = pd.DataFrame(np.random.choice(dates,100), columns=['dates']) 
# use toordinal() to get datenum 
df['ordinal'] = [x.toordinal() for x in df.dates] 

print(df) 

     dates ordinal 
0 2010-01-13 733785 
1 2010-01-16 733788 
2 2010-01-22 733794 
3 2010-01-01 733773 
4 2010-01-04 733776 
5 2010-01-28 733800 
6 2010-01-04 733776 
7 2010-01-08 733780 
8 2010-01-10 733782 
9 2010-01-20 733792 
..  ...  ... 
90 2010-01-19 733791 
91 2010-01-28 733800 
92 2010-01-01 733773 
93 2010-01-15 733787 
94 2010-01-04 733776 
95 2010-01-22 733794 
96 2010-01-13 733785 
97 2010-01-26 733798 
98 2010-01-11 733783 
99 2010-01-21 733793 

[100 rows x 2 columns]  

# plot non-parametric kde on numeric datenum 
ax = df['ordinal'].plot(kind='kde') 
# rename the xticks with labels 
x_ticks = ax.get_xticks() 
ax.set_xticks(x_ticks[::2]) 
xlabels = [dt.datetime.fromordinal(int(x)).strftime('%Y-%m-%d') for x in x_ticks[::2]] 
ax.set_xticklabels(xlabels) 

enter image description here

+2

很好的回答。這比我的答案強大得多,因爲它將正確處理閏年和1月1日以外的開始日期。我會將此推薦爲接受的答案。 – JohnE

3

我想有一些更好的和自動的方式來做到這一點,但如果沒有,那麼這應該是一個體面的解決方法。首先,讓我們建立了一些樣本數據:

np.random.seed(479) 
start_date = '2011-1-1' 
df = pd.DataFrame({ 'date':np.random.choice( 
        pd.date_range(start_date, periods=365*5, freq='D'), 50) }) 

df['rel'] = df['date'] - pd.to_datetime(start_date) 
df.rel = df.rel.astype('timedelta64[D]') 

     date rel 
0 2014-06-06 1252 
1 2011-10-26 298 
2 2013-08-24 966 
3 2014-09-25 1363 
4 2011-12-23 356 

正如你所看到的,「相對」僅僅是因爲起始日天數。它本質上是一個整數,所以你真正需要做的就是相對於開始日期對它進行規範化。

df['year_as_float'] = pd.to_datetime(start_date).year + df.rel/365. 

     date rel year_as_float 
0 2014-06-06 1252 2014.430137 
1 2011-10-26 298 2011.816438 
2 2013-08-24 966 2013.646575 
3 2014-09-25 1363 2014.734247 
4 2011-12-23 356 2011.975342 

你需要稍微調整,對於日期沒有啓動一月1這也忽略任何閏年這實在不是一個實際的問題,如果你只是產生一個KDE情節超過5年,但取決於你可能想做什麼,這可能很重要。

這裏的情節

df['year_as_float']d.plot(kind='kde') 

enter image description here