Как построить график KDE для уникальных устройств в час с помощью seaborn? - PullRequest
0 голосов
/ 02 августа 2020

У меня есть следующие pandas df (datetime имеет тип datetime64):

       device            datetime
0       846ee 2020-03-22 14:27:29
1       0a26e 2020-03-22 15:33:31
2       8a906 2020-03-27 16:19:06
3       6bf11 2020-03-27 16:05:20
4       d3923 2020-03-23 18:58:51

Я хотел использовать функцию KDE из distplot Сиборна. Хотя я не совсем понимаю, почему, у меня это сработало:

df['hour'] = df['datetime'].dt.floor('T').dt.time
df['hour'] = pd.to_timedelta(df['hour'].astype(str)) / pd.Timedelta(hours=1)

, а затем

sns.distplot(df['hour'], hist=False, bins=arr, label='tef')

Вопрос: как мне сделать то же самое, но только считать уникальный device с? Я пробовал

  1. df.groupby(['hour']).nunique().reset_index()
  2. df.groupby(['hour'])[['device']].size().reset_index()

Но они дают мне разные результаты (тот же порядок, но несколько больше или Меньше). Думаю, я не понимаю, что делаю в pd.to_timedelta(df['hour'].astype(str)) / pd.Timedelta(hours=1), и это мешает мне думать об уникальных способностях ... может быть.

Ответы [ 2 ]

1 голос
/ 03 сентября 2020
import pandas as pd
import numpy as np  # for test data
import random  # for test data

# test data
np.random.seed(365)
random.seed(365)
rows = 40
data = {'device': [random.choice(['846ee', '0a26e', '8a906', '6bf11', 'd3923']) for _ in range(rows)],
        'datetime': pd.bdate_range(datetime(2020, 7, 1), freq='15min', periods=rows).tolist()}

# create test dataframe
df = pd.DataFrame(data)

# this date column is already in a datetime format; for the real dataframe, make sure it's converted
# df.datetime = pd.to_datetime(df.datetime)

# this extracts the time component from the datetime and is a datetime.time object
df['time'] = df['datetime'].dt.floor('T').dt.time

# this creates a timedelta column; note it's format
df['timedelta'] = pd.to_timedelta(df['time'].astype(str))

# this creates a float representing the hour and its fractional component (minutes)
df['hours'] = pd.to_timedelta(df['time'].astype(str)) / pd.Timedelta(hours=1)

# extracts just the hour
df['hour'] = df['datetime'].dt.hour

display (df.head ())

  • Этот вид должен прояснить разницу между методами извлечения времени.
   device            datetime      time       timedelta  hours  hour
0   8a906 2020-07-01 00:00:00  00:00:00 0 days 00:00:00   0.00     0
1   0a26e 2020-07-01 00:15:00  00:15:00 0 days 00:15:00   0.25     0
2   8a906 2020-07-01 00:30:00  00:30:00 0 days 00:30:00   0.50     0
3   d3923 2020-07-01 00:45:00  00:45:00 0 days 00:45:00   0.75     0
4   0a26e 2020-07-01 01:00:00  01:00:00 0 days 01:00:00   1.00     1
5   d3923 2020-07-01 01:15:00  01:15:00 0 days 01:15:00   1.25     1
6   6bf11 2020-07-01 01:30:00  01:30:00 0 days 01:30:00   1.50     1
7   d3923 2020-07-01 01:45:00  01:45:00 0 days 01:45:00   1.75     1
8   6bf11 2020-07-01 02:00:00  02:00:00 0 days 02:00:00   2.00     2
9   d3923 2020-07-01 02:15:00  02:15:00 0 days 02:15:00   2.25     2
10  0a26e 2020-07-01 02:30:00  02:30:00 0 days 02:30:00   2.50     2
11  846ee 2020-07-01 02:45:00  02:45:00 0 days 02:45:00   2.75     2
12  0a26e 2020-07-01 03:00:00  03:00:00 0 days 03:00:00   3.00     3
13  846ee 2020-07-01 03:15:00  03:15:00 0 days 03:15:00   3.25     3
14  846ee 2020-07-01 03:30:00  03:30:00 0 days 03:30:00   3.50     3

Графическое устройство подсчитывает для каждого часа с seaborn.countplot

plt.figure(figsize=(8, 6))
sns.countplot(x='hour', hue='device', data=df)
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')

enter image description here

Plot a seaborn.distplot для каждого устройства

  • Используйте seaborn.FacetGrid
  • Это будет укажите почасовое распределение для каждого устройства.
import seaborn as sns
import matplotlib.pyplot as plt

g = sns.FacetGrid(df, row='device', height=5)
g.map(sns.distplot, 'hours', bins=24, kde=True)
g.set(xlim=(0, 24), xticks=range(0, 25, 1))

введите описание изображения здесь

1 голос
/ 02 августа 2020

Можете попробовать

df['hour'] = df['datetime'].dt.strftime('%Y-%m-%d %H')
s = df.groupby('hour')['device'].value_counts()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...