J'ai pris ma série et je l'ai contrainte à une colonne datetime de dtype = datetime64[ns]
(mais il ne faut que la résolution du jour ... je ne sais pas comment changer).
import pandas as pd
df = pd.read_csv('somefile.csv')
column = df['date']
column = pd.to_datetime(column, coerce=True)
mais le tracé ne fonctionne pas:
ipdb> column.plot(kind='hist')
*** TypeError: ufunc add cannot use operands with types dtype('<M8[ns]') and dtype('float64')
Je voudrais tracer un histogramme qui juste montre le nombre de dates par semaine, mois ou année.
Il y a sûrement un moyen de faire cela dans pandas
?
Étant donné ce df:
date
0 2001-08-10
1 2002-08-31
2 2003-08-29
3 2006-06-21
4 2002-03-27
5 2003-07-14
6 2004-06-15
7 2003-08-14
8 2003-07-29
et si ce n'est pas déjà le cas:
df["date"] = df["date"].astype("datetime64")
Pour afficher le nombre de dates par mois:
df.groupby(df["date"].dt.month).count().plot(kind="bar")
.dt
vous permet d'accéder aux propriétés datetime.
Ce qui vous donnera:
Vous pouvez remplacer mois par année, jour, etc.
Si vous voulez distinguer l'année et le mois par exemple, il suffit de faire:
df.groupby([df["date"].dt.year, df["date"].dt.month]).count().plot(kind="bar")
Qui donne:
Était-ce ce que tu voulais? Est-ce clair?
J'espère que cela t'aides !
Je pense que resample pourrait être ce que vous recherchez. Dans votre cas, faites-vous:
df.set_index('date', inplace=True)
# for '1M' for 1 month; '1W' for 1 week; check documentation on offset alias
df.resample('1M', how='count')
Il ne s'agit que de compter et non d'intrigue, vous devez donc créer vos propres parcelles.
Voir ce post pour plus de détails sur la documentation de resample documentation sur le rééchantillonnage des pandas
J'ai rencontré des problèmes similaires aux vôtres. J'espère que cela t'aides.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Create random datetime object."""
# core modules
from datetime import datetime
import random
# 3rd party modules
import pandas as pd
import matplotlib.pyplot as plt
def visualize(df, column_name='start_date', color='#494949', title=''):
"""
Visualize a dataframe with a date column.
Parameters
----------
df : Pandas dataframe
column_name : str
Column to visualize
color : str
title : str
"""
plt.figure(figsize=(20, 10))
ax = (df[column_name].groupby(df[column_name].dt.hour)
.count()).plot(kind="bar", color=color)
ax.set_facecolor('#eeeeee')
ax.set_xlabel("hour of the day")
ax.set_ylabel("count")
ax.set_title(title)
plt.show()
def create_random_datetime(from_date, to_date, Rand_type='uniform'):
"""
Create random date within timeframe.
Parameters
----------
from_date : datetime object
to_date : datetime object
Rand_type : {'uniform'}
Examples
--------
>>> random.seed(28041990)
>>> create_random_datetime(datetime(1990, 4, 28), datetime(2000, 12, 31))
datetime.datetime(1998, 12, 13, 23, 38, 0, 121628)
>>> create_random_datetime(datetime(1990, 4, 28), datetime(2000, 12, 31))
datetime.datetime(2000, 3, 19, 19, 24, 31, 193940)
"""
delta = to_date - from_date
if Rand_type == 'uniform':
Rand = random.random()
else:
raise NotImplementedError('Unknown random mode \'{}\''
.format(Rand_type))
return from_date + Rand * delta
def create_df(n=1000):
"""Create a Pandas dataframe with datetime objects."""
from_date = datetime(1990, 4, 28)
to_date = datetime(2000, 12, 31)
sales = [create_random_datetime(from_date, to_date) for _ in range(n)]
df = pd.DataFrame({'start_date': sales})
return df
if __== '__main__':
import doctest
doctest.testmod()
df = create_df()
visualize(df)
J'ai pu contourner ce problème en (1) traçant avec matplotlib au lieu d'utiliser directement le cadre de données et (2) en utilisant l'attribut values
. Voir exemple:
import matplotlib.pyplot as plt
ax = plt.gca()
ax.hist(column.values)
Cela ne fonctionne pas si je n'utilise pas values
, mais je ne sais pas pourquoi cela fonctionne.
J'avais juste des problèmes avec ça aussi. J'imagine que puisque vous travaillez avec des dates, vous souhaitez conserver l'ordre chronologique (comme je l'ai fait).
La solution de contournement est alors
import matplotlib.pyplot as plt
counts = df['date'].value_counts(sort=False)
plt.bar(counts.index,counts)
plt.show()
S'il vous plaît, si quelqu'un connaît une meilleure façon, s'il vous plaît parlez-en.
EDIT: pour jean ci-dessus, voici un échantillon des données [j'ai échantillonné de manière aléatoire à partir de l'ensemble de données complet, d'où les données triviales de l'histogramme.]
print dates
type(dates),type(dates[0])
dates.hist()
plt.show()
Sortie:
0 2001-07-10
1 2002-05-31
2 2003-08-29
3 2006-06-21
4 2002-03-27
5 2003-07-14
6 2004-06-15
7 2002-01-17
Name: Date, dtype: object
<class 'pandas.core.series.Series'> <type 'datetime.date'>
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-38-f39e334eece0> in <module>()
2 print dates
3 print type(dates),type(dates[0])
----> 4 dates.hist()
5 plt.show()
/anaconda/lib/python2.7/site-packages/pandas/tools/plotting.pyc in hist_series(self, by, ax, grid, xlabelsize, xrot, ylabelsize, yrot, figsize, bins, **kwds)
2570 values = self.dropna().values
2571
-> 2572 ax.hist(values, bins=bins, **kwds)
2573 ax.grid(grid)
2574 axes = np.array([ax])
/anaconda/lib/python2.7/site-packages/matplotlib/axes/_axes.pyc in hist(self, x, bins, range, normed, weights, cumulative, bottom, histtype, align, orientation, rwidth, log, color, label, stacked, **kwargs)
5620 for xi in x:
5621 if len(xi) > 0:
-> 5622 xmin = min(xmin, xi.min())
5623 xmax = max(xmax, xi.max())
5624 bin_range = (xmin, xmax)
TypeError: can't compare datetime.date to float
Je pense que pour résoudre ce problème, vous pouvez utiliser ce code, il convertit le type de date en types int:
df['date'] = df['date'].astype(int)
df['date'] = pd.to_datetime(df['date'], unit='s')
pour obtenir la date seulement, vous pouvez ajouter ce code:
pd.DatetimeIndex(df.date).normalize()
df['date'] = pd.DatetimeIndex(df.date).normalize()