[英]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.