【问题标题】:Python & Pandas - Group by day and count for each dayPython & Pandas - 按天分组并计算每一天
【发布时间】:2018-08-04 08:07:37
【问题描述】:

我是 pandas 的新手,现在我不知道如何安排我的时间系列,看看吧:

date & time of connection
19/06/2017 12:39
19/06/2017 12:40
19/06/2017 13:11
20/06/2017 12:02
20/06/2017 12:04
21/06/2017 09:32
21/06/2017 18:23
21/06/2017 18:51
21/06/2017 19:08
21/06/2017 19:50
22/06/2017 13:22
22/06/2017 13:41
22/06/2017 18:01
23/06/2017 16:18
23/06/2017 17:00
23/06/2017 19:25
23/06/2017 20:58
23/06/2017 21:03
23/06/2017 21:05

这是 130 k 原始数据集的样本,我尝试过: df.groupby('date & time of connection')['date & time of connection'].apply(list)

我猜还不够

我想我应该:

  • 创建一个索引从 dd/mm/yyyy 到 dd/mm/yyyy 的字典
  • 将“连接的日期和时间”类型 dateTime 转换为 Date
  • “连接日期和时间”的分组和计数日期
  • 把我数到的数字放进字典里?

你觉得我的逻辑怎么样?你知道一些tutos吗? 非常感谢

【问题讨论】:

  • 重新接受的理由是什么?你不喜欢我的解决方案?

标签: python python-3.x pandas time-series


【解决方案1】:

嘿,我找到了使用重采样的简单方法。

# Set the date column as index column.
df = df.set_index('your_date_column')

# Make counts
df_counts = df.your_date_column.resample('D').count() 

虽然你的栏目名称很长而且包含空格,这让我有点畏缩。我会使用破折号而不是空格。

【讨论】:

  • 您无需将date column 设为index。您可以改用onresample('D',on='your_date_column')
【解决方案2】:

您可以使用dt.floor 转换为dates,然后使用value_countsgroupbysize

df = (pd.to_datetime(df['date & time of connection'])
       .dt.floor('d')
       .value_counts()
       .rename_axis('date')
       .reset_index(name='count'))
print (df)
        date  count
0 2017-06-23      6
1 2017-06-21      5
2 2017-06-19      3
3 2017-06-22      3
4 2017-06-20      2

或者:

s = pd.to_datetime(df['date & time of connection'])
df = s.groupby(s.dt.floor('d')).size().reset_index(name='count')
print (df)
  date & time of connection  count
0                2017-06-19      3
1                2017-06-20      2
2                2017-06-21      5
3                2017-06-22      3
4                2017-06-23      6

时间安排

np.random.seed(1542)

N = 220000
a = np.unique(np.random.randint(N, size=int(N/2)))
df = pd.DataFrame(pd.date_range('2000-01-01', freq='37T', periods=N)).drop(a)
df.columns = ['date & time of connection']
df['date & time of connection'] = df['date & time of connection'].dt.strftime('%d/%m/%Y %H:%M:%S')
print (df.head()) 

In [193]: %%timeit
     ...: df['date & time of connection']=pd.to_datetime(df['date & time of connection'])
     ...: df1 = df.groupby(by=df['date & time of connection'].dt.date).count()
     ...: 
539 ms ± 45.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [194]: %%timeit
     ...: df1 = (pd.to_datetime(df['date & time of connection'])
     ...:        .dt.floor('d')
     ...:        .value_counts()
     ...:        .rename_axis('date')
     ...:        .reset_index(name='count'))
     ...: 
12.4 ms ± 350 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [195]: %%timeit
     ...: s = pd.to_datetime(df['date & time of connection'])
     ...: df2 = s.groupby(s.dt.floor('d')).size().reset_index(name='count')
     ...: 
17.7 ms ± 140 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

【讨论】:

    【解决方案3】:

    确保您的列采用日期格式。

    df['date & time of connection']=pd.to_datetime(df['date & time of connection'])
    

    然后您可以按日期对数据进行分组并进行计数:

    df.groupby(by=df['date & time of connection'].dt.date).count()
    Out[10]: 
                               date & time of connection
    date & time of connection                           
    2017-06-19                                         3
    2017-06-20                                         2
    2017-06-21                                         5
    2017-06-22                                         3
    2017-06-23                                         6
    

    【讨论】:

    • 使用.dt.date 比使用上面的floor 函数要优雅得多。
    • 为了让它更漂亮一点,如果我们只在输出中看到 datecount 列会更好,就像接受的答案一样。如果df 有多个列,则此代码将导致有多余的列,这对于演示文稿来说不是那么漂亮!
    猜你喜欢
    • 2017-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多