我正在将csv文件加载到pandas数据帧中。我想绘制结果数据的直方图。
我的一些专栏是日期。 Pandas使用数据类型datetime64 [ns]来存储它们。对于我的日期,我想在x轴上放置正确的日期格式化x刻度标记。
以下是一些不起作用的代码:
import pandas
import numpy as np
import os
from datetime import datetime
from matplotlib import pyplot as plt
dirname='/my_working_dir/'
in_filename=os.path.join(dirname,'input_data.csv')
df = pandas.read_csv(in_filename,parse_dates=['Date of event'],dayfirst=True)
failures=df[df['Failure']==True];
suspensions=df[df['Failure']==False];
f=failures['Date of event'].dropna()
s=suspensions['Date of event'].dropna()
fig, ax = plt.subplots()
ax.hist([f,s],40,weights=[np.zeros_like(f) + 1. / f.size,
np.zeros_like(s) + 1. / s.size],
color=['r','g']);
ax.set_yticklabels(['{:.0f}%'.format(x*100)
for x in plt.gca().get_yticks()])
numbers=ax.get_xticks();
labels=map(lambda x: datetime.fromtimestamp(x).strftime('%Y-%m-%d'), numbers)
plt.xticks(numbers, labels)
错误:
Traceback (most recent call last):
File "datetest.py", line 22, in <module>
ax.hist([f,s],40,weights=[np.zeros_like(f) + 1. / f.size,
TypeError: ufunc add cannot use operands with types dtype('<M8[ns]') and dtype('float64')
我知道这是相当多的代码,但问题在于整合整个事情,我愿意更改任何部分(读取数据,或绘图,或设置xlabels)以获得它工作
我尝试过的事情:
df['int_date']=df['Date of event'].view('int64')
制作日期数据的整数版本。这让我可以绘制出我需要的直方图。 x的范围是1e18到1.5e18,我无法弄清楚如何获得正确的日期格式xticks。df['test']=((df['Date of event'] - np.datetime64('1970-01-01T00:00:00Z')) / np.timedelta64(1, 's'))
转换为时间戳(如另一个堆栈溢出帖子中所示)我得到:“TypeError:输入类型不支持ufunc'isnan',并且无法安全地强制输入根据投射规则''safe''任何支持的类型“我的numpy是版本1.10.4,我无法在我的系统上安装新库或升级。以下是csv文件的一些简化内容(我的实际数据要大得多):
Index,Date of event,Failure
12421,18/11/2016,TRUE
12409,01/05/2017,FALSE
12410,29/03/2017,FALSE
12453,21/08/2016,TRUE
12454,01/08/2016,TRUE
How can I convert pandas date time xticks to readable format?中的答案并没有解决我的问题 - 我甚至无法使用我的数据的情节仍处于datetime64格式。在那个问题中,有工作xticks,但他们只需要重新格式化。
感谢您提供任何帮助。
答案 0 :(得分:2)
你有两个问题。
第一个是weights
列表。 np.zeros_like(f)
不会给出任何有用的东西,因为首先,f是一个系列,而不是一个numpy数组,第二,它由日期组成,但是日期方面的零是什么?
你真正想要的是一个零的数组,其长度与f
相同。这可以通过np.zeros(len(f))
或np.zeros(f.size)
获得。
其次,你不能直接使用该系列,但需要取其值:ax.hist([f.values, s.values])
而不是ax.hist([f, s])
所以总的来说:
weights = [np.zeros(len(f)) + 1. / f.size, np.zeros(len(s)) + 1. / s.size]
ax.hist([f.values, s.values],40,weights=weights, color=['r','g'])
此时您可能会考虑格式化x轴,但是,这会导致新的错误,因此我建议将其保留,如果需要,请坚持使用类似于此问题中提供的解决方案{{3 }}
一个完整的例子:
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import numpy as np
dates = pd.date_range("2013-01-01", "2017-06-20" )
y = np.cumsum(np.random.normal(size=len(dates)))
fail = np.random.choice([True, False], size=len(dates))
df = pd.DataFrame({'Date of event':dates, "y":y, 'Failure':fail})
failures=df[df['Failure']==True];
suspensions=df[df['Failure']==False];
f=failures['Date of event'].dropna()
s=suspensions['Date of event'].dropna()
fig, ax = plt.subplots()
weights=[np.zeros(len(f)) + 1. / f.size, np.zeros(len(s)) + 1. / s.size]
ax.hist([f.values, s.values],40,weights=weights,
color=['r','g'])
ax.set_yticklabels(['{:.1f}%'.format(x*100)
for x in plt.gca().get_yticks()])
fig.autofmt_xdate()
plt.show()
How can I convert pandas date time xticks to readable format?