![](/img/trans.png)
[英]How to plot percentage with seaborn distplot / histplot / displot
[英]How to plot Pandas datetime series in Seaborn distplot?
我有一個帶有日期時間列的熊貓數據框。 我想根據該日期列繪制行的分布,但我目前遇到了一個無益的錯誤。 我有:
df['Date'] = pd.to_datetime(df['Date'], errors='raise')
s = sns.distplot(df['Date'])
拋出錯誤:
TypeError: ufunc add cannot use operands with types dtype('<M8[ns]') and dtype('<M8[ns]')
如果我將要繪制的列更改為數字數據,則一切正常。 我怎樣才能讓日期時間列表現得很好? 我在文檔中找不到太多關於我認為我需要的內容。 任何和所有的幫助表示贊賞。
以下是df.head(2)
的結果,出於安全原因等,我刪除了一些列:
Date
2812 2016-03-05
2813 2016-03-05
顯然該列(作為一個系列)具有屬性
Name: Date, dtype: datetime64[ns]
我自己遇到了同樣的問題時遇到了這個問題。 正如評論中提到的,seaborn 的distplot
似乎不支持使用日期。 不幸的是,我在官方文檔中找不到任何內容來支持這一說法。
我找到了兩種方法來處理這個問題。 它們都不是完美的,但這是我發現的最好的。
選項 1:將日期轉換為數字
轉換為一些數字度量並使用它。 displot
處理數字,所以如果每個日期都用一個數字表示,我們就可以了。 日期和數字之間的映射有點像使用 MinMax Scaler。 例如,我們可以設置“2017-01-01”為0,“2020-06-06”為1,並將它們之間的所有日期映射到[0,1]范圍內的值。
使用的數字范圍取決於您的數據范圍,可能是天/月/年等。
我將通過這個玩具示例演示這種方法。
import pandas as pd
import datetime as dt
original_dates = ["2016-03-05", "2016-03-05", "2016-02-05", "2016-02-05", "2016-02-05", "2014-03-05"]
dates_list = [dt.datetime.strptime(date, '%Y-%m-%d').date() for date in original_dates]
df = pd.DataFrame({"Date":dates_list})
現在數據框如下:
Date
0 2016-03-05
1 2016-03-05
2 2016-02-05
3 2016-02-05
4 2016-02-05
5 2014-03-05
(當然,這不是將日期輸入到數據框的最佳方式,但方式無關緊要)。
現在我創建一個新列,它將保存最小日期之間的天數差異:
df["NewDate"] = df["Date"] - dt.date(2014,3,5)
df["NewDate"] = df["NewDate"].apply(lambda x: x.days)
結果:
Date NewDate
0 2016-03-05 731
1 2016-03-05 731
2 2016-02-05 702
3 2016-02-05 702
4 2016-02-05 702
5 2014-03-05 0
注意我“硬編碼”了最小日期。 您可以使用更好的方法來查找最小值而不是對其進行硬編碼。 我只是想盡快得到這部分。
現在我們可以在我們的新列上使用displot
:
import seaborn as sns
sns.set()
ax = sns.distplot(df['NewDate'])
輸出:
如您所見,它顯示的是日期而不是日期。 對於我的個人問題,以這種方式展示它是可以的。 如果要將其顯示為日期,則需要一些額外的步驟: 顯示 x 軸函數的 xticks,而不是直接顯示數據本身。 日期示例(熊貓,matplotlib)
正如我之前所說,我使用天差縮放,但您可以使用數月或數年進行相同的縮放。 取決於數據。
選項2:直接使用直方圖,不用seaborn的displot
在這個問題中: Pandas 可以繪制日期的直方圖嗎? 有一個答案如何使用熊貓的groupby
繪制帶有日期的直方圖。
它與displot
,但它可以是足夠接近的解決方案(因為 displot 最終基於 matplotlib 的歷史)。
您可以將日期轉換為 Categorical 類型,並繪制結果代碼(整數)。 然后,用日期(作為類別)標記 x-ticks。
import pandas as pd
import seaborn as sns
original_dates = [
"2016-03-05", "2016-03-05", "2016-02-05",
"2016-02-05", "2016-02-05", "2014-03-05"]
dates_list = pd.to_datetime(original_dates)
df = pd.DataFrame({"Date": dates_list})
df['date-as-cat'] = df['Date'].astype('category') # new
df['codes'] = df['date-as-cat'].cat.codes # new
print(df)
print(df.dtypes)
Date date-as-cat codes
0 2016-03-05 2016-03-05 2
1 2016-03-05 2016-03-05 2
2 2016-02-05 2016-02-05 1
3 2016-02-05 2016-02-05 1
4 2016-02-05 2016-02-05 1
5 2014-03-05 2014-03-05 0
Date datetime64[ns]
date-as-cat category
codes int8
dtype: object
date-as-code 和 date-as-category 信息是這樣獲得的:
x = df[['codes', 'date-as-cat']].drop_duplicates().sort_values('codes')
print(x)
codes date-as-cat
5 0 2014-03-05
2 1 2016-02-05
0 2 2016-03-05
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.