क्या पंडों की तारीखों का एक हिस्टोग्राम साजिश कर सकता है?


104

मैंने अपनी श्रृंखला ले ली है और इसे dtype = 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

जवाबों:


169

इस 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 आप डेटाटाइम गुणों तक पहुँचने की अनुमति देता है।

जो आपको देगा:

सामूहिक तिथि

आप महीने को साल, दिन, आदि से बदल सकते हैं।

यदि आप उदाहरण के लिए वर्ष और महीने को अलग करना चाहते हैं, तो बस यह करें:

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

जो देता है:

ग्रुप की तारीख माह वर्ष

यह वही था जो आप चाहते थे? क्या यह स्पष्ट है?

उम्मीद है की यह मदद करेगा !


1
यदि आपके पास कई वर्षों का डेटा है, तो सभी 'पुराने' डेटा एक ही कॉलम में डाल दिए जाते हैं और प्रत्येक महीने के लिए।
ड्रेविको

काम करता है, लेकिन मेरे लिए (पांडा 0.15.2) तारीखों को राजधानी डी के साथ लिखा जाना चाहिए: df.groupby (df.Date.dt.month) .count ()। Plot (तरह = "बार")
harbun

@drevicko: उम्मीद है कि मुझे विश्वास है। @harbun: dateया Dateयहां कॉलम नाम हैं, इसलिए यदि आपके कॉलम को तारीखों के साथ फू कहा जाता है, तो यह होगा:df.foo.dt.month
jrjc

@jeanrjc प्रश्न पर फिर से देखते हुए, मुझे लगता है कि आप सही हैं। मेरे जैसे अन्य लोगों के लिए जिन्हें वर्षों से अलग करने की आवश्यकता है, क्या groupbyकॉलम डेटा की दो विशेषताओं के संयोजन का एक सरल तरीका है (उदाहरण: वर्ष और दिनांक)?
ड्रेविको

क्या तिथियों को तैयार करने का कोई तरीका है ताकि मैं तारीखों के ऊपर हिस्टोग्राम का उपयोग करने के लिए seaborn.distplot () का उपयोग कर सकूं?
पैन

11

मुझे लगता है कि आप जिस चीज की तलाश में हैं, उसे फिर से शुरू किया जा सकता है। आपके मामले में, क्या करें:

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

यह केवल काउंटिंग कर रहा है न कि प्लॉट, इसलिए आपको फिर अपने प्लॉट बनाने होंगे।

पुनरावर्तन पंडों के पुनरावर्तन प्रलेखन के बारे में अधिक जानकारी के लिए इस पोस्ट को देखें

आप जैसी समस्याओं में भागे हैं, वैसे ही मैं भी हूं। उम्मीद है की यह मदद करेगा।


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) के आसपास काम करने में सक्षम था matlotlib के साथ सीधे डेटाफ़्रेम का उपयोग करने के बजाय और (2) valuesविशेषता का उपयोग करके । उदाहरण देखें:

import matplotlib.pyplot as plt

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

अगर मैं उपयोग नहीं करता तो यह काम नहीं करता values, लेकिन मुझे नहीं पता कि यह क्यों काम करता है।


3

यहाँ एक समाधान है जब आप सिर्फ एक हिस्टोग्राम करना चाहते हैं जैसे आप इसकी उम्मीद करते हैं। यह ग्रुपबी का उपयोग नहीं करता है, लेकिन डेटाटाइम मान को पूर्णांकों में परिवर्तित करता है और प्लॉट पर लेबल बदलता है। टिक लेबल को यहां तक ​​कि स्थानों पर ले जाने के लिए कुछ सुधार किया जा सकता है। इसके अलावा एक कर्नेल घनत्व अनुमान भूखंड (और किसी भी अन्य भूखंड) के साथ भी संभव है।

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
यह इस सवाल का जवाब नहीं देता है कि एक ऑर्डर किए गए डेटाइम हिस्टोग्राम की साजिश कैसे करें?
लॉलेरकोस्टर

मुझे लगता है कि आपकी समस्या

आप इस लिंक को

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। क्या आप उस मामले पर एक नोट जोड़ने पर विचार करेंगे?
डेविड जेड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.