Pandas可以绘制日期的直方图吗?

lol*_*ter 80 python time-series matplotlib pandas

我接受了我的系列并将其强制转换为dtype =的日期时间列datetime64[ns](虽然只需要一天的分辨率......不确定如何更改).

import pandas as pd
df = pd.read_csv('somefile.csv')
column = df['date']
column = pd.to_datetime(column, coerce=True)
Run Code Online (Sandbox Code Playgroud)

但绘图不起作用:

ipdb> column.plot(kind='hist')
*** TypeError: ufunc add cannot use operands with types dtype('<M8[ns]') and dtype('float64')
Run Code Online (Sandbox Code Playgroud)

我想绘制一个直方图,只显示按周,月或年的日期计数.

当然有办法做到这一点pandas

jrj*_*rjc 131

鉴于此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
Run Code Online (Sandbox Code Playgroud)

而且,如果不是这样的话:

df["date"] = df["date"].astype("datetime64")
Run Code Online (Sandbox Code Playgroud)

要按月显示日期计数:

df.groupby(df["date"].dt.month).count().plot(kind="bar")
Run Code Online (Sandbox Code Playgroud)

.dt 允许您访问日期时间属性.

哪个会给你:

groupby日期月份

您可以逐年,每天等替换.

例如,如果要区分年份和月份,只需执行以下操作:

df.groupby([df["date"].dt.year, df["date"].dt.month]).count().plot(kind="bar")
Run Code Online (Sandbox Code Playgroud)

这使:

groupby日期月份

这是你想要的吗?这个清楚吗?

希望这可以帮助 !

  • 如果您有跨越几年的数据,则所有“一月”数据都会放入同一列中,依此类推。 (3认同)
  • @drevicko; 我编辑了.这是你想要的吗? (3认同)

Bri*_*lie 12

所有这些答案似乎都过于复杂,至少对于“现代”熊猫来说,它是两行。

df.set_index('date', inplace=True)
df.resample('M').size().plot.bar()
Run Code Online (Sandbox Code Playgroud)

如果您有一个带有 a 的系列DatetimeIndex,则只需运行第二行

series.resample('M').size().plot.bar() # Just counts the rows/month
or
series.resample('M').sum().plot.bar(). # Sums up the values in the series
Run Code Online (Sandbox Code Playgroud)

  • 这似乎仅在您有“DataFrame”时才有效,但如果您只有“Series”则无效。您会考虑在该案例中添加注释吗? (4认同)

Eth*_*han 8

我认为重新取样可能就是你要找的东西.在你的情况下,做:

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')
Run Code Online (Sandbox Code Playgroud)

它只是在进行计数而不是情节,所以你必须制作自己的情节.

有关resample pandas resample文档的文档的更多详细信息,请参阅此文章

我遇到了类似的问题.希望这可以帮助.

  • “如何”已被弃用。新语法是“df.resample('1M').count()” (5认同)

Jul*_*Wgs 7

当您只想获得您期望的直方图时,这是一个解决方案。这不使用 groupby,而是将日期时间值转换为整数并更改绘图上的标签。可以进行一些改进以将刻度标签移动到偶数位置。此外,通过方法,内核密度估计图(和任何其他图)也是可能的。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

df = pd.DataFrame({"datetime": pd.to_datetime(np.random.randint(1582800000000000000, 1583500000000000000, 100, dtype=np.int64))})
fig, ax = plt.subplots()
df["datetime"].astype(np.int64).plot.hist(ax=ax)
labels = ax.get_xticks().tolist()
labels = pd.to_datetime(labels)
ax.set_xticklabels(labels, rotation=90)
plt.show()
Run Code Online (Sandbox Code Playgroud)

日期时间直方图

  • `labels = pd.to_datetime(labels).strftime('%-m/%-d')` 可以帮助清理这些刻度标签。 (3认同)

abe*_*bop 5

我能够通过(1)使用 matplotlib 绘图而不是直接使用数据框和(2)使用values属性来解决这个问题。见示例:

import matplotlib.pyplot as plt

ax = plt.gca()
ax.hist(column.values)
Run Code Online (Sandbox Code Playgroud)

如果我不使用values,这将不起作用,但我不知道它为什么起作用。


Mar*_*oma 5

渲染的例子

在此输入图像描述

示例代码

#!/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 __name__ == '__main__':
    import doctest
    doctest.testmod()
    df = create_df()
    visualize(df)
Run Code Online (Sandbox Code Playgroud)