Plotting unique values in pandas
<p>I have a data frame where the first column is time and the second is a letter:</p>

<pre><code>Time                Letter 
2016-10-05 20:46:12 'A'
2016-10-05 20:47:12 'A'
2016-10-05 20:50:12 'B'
2016-10-06 00:46:12 'A'
2016-10-06 01:46:12 'B'
2016-10-06 01:47:12 'C'
2016-10-06 02:46:12 'D'
</code></pre>

<p>I need to group the data by hour and count number of unique letters per hour:</p>

<pre><code>Time          Unique_values
2016-10-05 20 2
2016-10-06 00 1
2016-10-06 01 2
2016-10-06 00 1

df.groupby([df.index.date,df.index.hour]).Letter.nunique().plot(kind = 'bar', rot =0)
</code></pre>

<p>provides the plot with labels like (2016-10-05,7), (2016-10-05,8)...</p>

<p>Is there any way to remove the brackets and instead of 7, 8 etc. use 07:00:00, 08:00:00?</p>

<p>You can remove minutes and seconds by converting column <code>Time</code> to <code>numpy array</code> by <a href="http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.values.html" rel="nofollow"><code>values</code></a> and then <code>groupby</code>:</p>

<pre><code>print (df.Time.values.astype('&lt;M8[h]'))
['2016-10-05T20' '2016-10-05T20' '2016-10-05T20' '2016-10-06T00'
 '2016-10-06T01' '2016-10-06T01' '2016-10-06T02']


print (df.groupby([df.Time.values.astype('&lt;M8[h]')])['Letter'].nunique())
2016-10-05 20:00:00    2
2016-10-06 00:00:00    1
2016-10-06 01:00:00    2
2016-10-06 02:00:00    1
Name: Letter, dtype: int64
</code></pre>

<p><strong>Timings</strong>:</p>

<pre><code>In [72]: %timeit (df.groupby([df.Time.values.astype('&lt;M8[h]')])['Letter'].nunique())
100 loops, best of 3: 7.94 ms per loop

In [73]: %timeit (ayh1(df1))
1 loop, best of 3: 301 ms per loop

In [74]: %timeit (ayh2(df2))
1 loop, best of 3: 298 ms per loop
</code></pre>

<p><strong>Code</strong>:</p>

<pre><code>start = pd.to_datetime('2015-02-24 20:00:15')
rng = pd.date_range(start, periods=10000, freq='40T')
df = pd.DataFrame({'Time': rng, 
                    'Letter': np.random.choice(list(ascii_letters.upper()), (10000,))})  
print (df)

df1 = df.copy()
df2 = df.copy()

def ayh1(df):
    ser = df.groupby(pd.Grouper(key='Time', freq='H'))['Letter'].agg(pd.Series.nunique)
    return ser[ser&gt;0]

def ayh2(df):
    ser = df.set_index('Time').resample('H')['Letter'].agg(pd.Series.nunique)
    return ser[ser&gt;0]

print (df.groupby([df.Time.values.astype('&lt;M8[h]')])['Letter'].nunique())

print (ayh1(df1))
print (ayh2(df2))
</code></pre>

python pandas