Pandas는 날짜 히스토그램을 그릴 수 있습니까?


101

내 시리즈를 가져와 dtype =의 datetime 열로 강제 적용했습니다 datetime64[ns](일일 해상도 만 필요하지만 변경 방법은 확실하지 않음).

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

하지만 플로팅이 작동하지 않습니다.

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

주, 월 또는 연도별로 날짜 수를 보여주는 히스토그램을 플로팅하고 싶습니다 .

확실히 이것을 할 방법이 pandas있습니까?


2
가지고있는 df의 샘플을 보여줄 수 있습니까?
jrjc

답변:


164

이 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

그리고 아직 그렇지 않은 경우 :

df["date"] = df["date"].astype("datetime64")

월별 날짜 수를 표시하려면 :

df.groupby(df["date"].dt.month).count().plot(kind="bar")

.dt datetime 속성에 액세스 할 수 있습니다.

당신에게 줄 것 :

그룹 별 날짜 월

년, 일 등으로 월을 바꿀 수 있습니다.

예를 들어 연도와 월을 구별하려면 다음을 수행하십시오.

df.groupby([df["date"].dt.year, df["date"].dt.month]).count().plot(kind="bar")

다음을 제공합니다.

그룹 별 날짜 월 년

당신이 원했던 것이 었습니까? 이것이 분명합니까?

도움이 되었기를 바랍니다 !


1
여러 해에 걸친 데이터가있는 경우 모든 '1 월'데이터가 매월 동일한 열에 저장되는 방식입니다.
drevicko 2015

작동하지만 나를 위해 (pandas 0.15.2) 날짜는 대문자 D로 작성해야합니다 : df.groupby (df.Date.dt.month) .count (). plot (kind = "bar")
harbun

@drevicko : 그것은 내가 믿는 것으로 예상됩니다. @harbun : date또는 Date여기에 열 이름이 있습니다. 날짜가있는 열의 이름이 foo이면 다음과 같습니다.df.foo.dt.month
jrjc

@jeanrjc 질문을 다시 보면 당신이 옳은 것 같아요. 연도별로 구분해야하는 저와 같은 다른 사용자에게는 groupby열 데이터의 두 속성 조합 (예 : 연도 및 날짜)에 대한 간단한 방법이 있습니까?
drevicko 2015-06-14

seaborn.distplot ()을 사용하여 날짜에 대한 날짜 히스토그램을 그릴 수 있도록 날짜를 준비하는 방법이 있습니까?
panc

11

나는 resample이 당신이 찾고있는 것일 수 있다고 생각합니다. 귀하의 경우 다음을 수행하십시오.

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')

플롯이 아닌 계산 만 수행하므로 자신 만의 플롯을 만들어야합니다.

resample pandas resample 문서 의 문서에 대한 자세한 내용은이 게시물을 참조하세요.

나는 당신과 비슷한 문제에 부딪 혔습니다. 도움이 되었기를 바랍니다.


2
how더 이상 사용되지 않습니다. 새로운 구문은df.resample('1M').count()
댄 위버

6

렌더링 된 예

여기에 이미지 설명 입력

예제 코드

#!/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)

5

나는 (1) 데이터 프레임을 직접 사용하는 대신 matplotlib로 플로팅하고 (2) values속성을 사용하여이 문제를 해결할 수 있었습니다. 예보기 :

import matplotlib.pyplot as plt

ax = plt.gca()
ax.hist(column.values)

을 사용하지 않으면 작동 values하지 않지만 왜 작동하는지 모르겠습니다.


3

예상대로 히스토그램을 원할 때를위한 솔루션이 있습니다. 이것은 groupby를 사용하지 않지만 datetime 값을 정수로 변환하고 플롯의 레이블을 변경합니다. 눈금 레이블을 짝수 위치로 이동하기 위해 약간의 개선이 이루어질 수 있습니다. 또한 접근 방식을 사용하면 커널 밀도 추정 플롯 (및 기타 플롯)도 가능합니다.

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()

날짜 시간 히스토그램


1

나는 그 문제를 해결하기 위해 다음 코드를 사용할 수 있다고 생각합니다. 날짜 유형을 int 유형으로 변환합니다.

df['date'] = df['date'].astype(int)
df['date'] = pd.to_datetime(df['date'], unit='s')

날짜 만 얻기 위해 다음 코드를 추가 할 수 있습니다.

pd.DatetimeIndex(df.date).normalize()
df['date'] = pd.DatetimeIndex(df.date).normalize()

1
이것은 정렬 된 datetime 히스토그램을 그리는 방법에 대한 질문에 대답하지 않습니까?
lollercoaster

날짜 시간 유형에서 문제가 있다고 생각합니다. 플롯하기 전에 정규화해야합니다

당신이 볼 수있는 링크

1

나는 이것에도 문제가 있었다. 나는 당신이 날짜로 작업하고 있기 때문에 시간 순서를 보존하기를 원한다고 생각합니다.

해결 방법은 다음과 같습니다.

import matplotlib.pyplot as plt    
counts = df['date'].value_counts(sort=False)
plt.bar(counts.index,counts)
plt.show()

더 나은 방법을 아는 사람이 있으면 제발 말씀해주십시오.

편집 : 위의 진에 대한 데이터 샘플이 있습니다. [전체 데이터 세트에서 무작위로 샘플링 했으므로 사소한 히스토그램 데이터입니다.]

print dates
type(dates),type(dates[0])
dates.hist()
plt.show()

산출:

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

1

이 모든 대답은 지나치게 복잡해 보입니다. 최소한 '현대적인'판다에서는 두 줄입니다.

df.set_index('date', inplace=True)
df.resample('M').size().plot.bar()

1
이것은 당신이 가지고있는 경우에만 작동하는 것처럼 DataFrame보이지만 당신이 가지고있는 모든 것이 Series. 이 경우에 메모를 추가해 주시겠습니까?
David Z
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.