首页 > 解决方案 > 使用 Pandas Groupby 对时间值进行分组

问题描述

所以我有一个包含来自 Django 数据库的过滤数据的对象。数据包含格式为:YYYY-MM-DD HH:MM:SS 的时间值列表,我试图将每一秒分组到相应的分钟,将每分钟分组到相应的小时。然后我需要将这个分组传递给我的网站前端使用 Javascript。

到目前为止,我有进行分组的代码,虽然它不完全是我想要的,但代码和输出如下所示:

# Makes pd dataframe of database object, sets dateTime as index so we can easily extract hour, min, sec later
queryToDataFrame = pd.DataFrame(filterTable.values()[1:],columns=filterTable.values()[0]).set_index('dateTime')
        
hours = queryToDataFrame.index.hour # extracts hours from dataframe
minutes = queryToDataFrame.index.minute
seconds = queryToDataFrame.index.second
        
timepd = pd.DataFrame({'hours':hours, 'minutes':minutes, 'seconds':seconds}) # puts time values into new dataframe for easier processing
groupVar = timepd.groupby([timepd.hours, timepd.minutes]).apply(print) # groups minutes to hours and seconds to mins

输出

小时 分钟
0 20 52 10
1 20 52 30
2 20 52 35
小时 分钟
3 20 53 0
4 20 53 5
5 20 53 10

...

这与我试图获得的正确分组非常接近,但我实际上希望看起来像这样:

小时 分钟
0 20 52 0
1 5
2 10
3 53 0
4 5
5 21 1 0

只有一分钟值对应于属于该分钟类别的所有秒数,并且对于小时数相同。

我见过类似的例子,但到目前为止,这些例子都不同,足以让这个任务让我非常困惑。仅使用熊猫就可以完成吗?或者也许有不同的方法来实现这一目标?这段代码将处理的数据预计会非常大,所以我试图避免使用循环。

如果您需要一些数据来测试,这就是“queryToDataFrame”变量转换为数据框的内容:

<QuerySet [{'id': 10063705, 'valueName': 'Temp', 'value': 3.3, 'units': 'C', 'dateTime': datetime.datetime(2021, 3, 18, 20, 51, 50, tzinfo=<UTC>), 'timestamp': 1616122310.0}, 
{'id': 10063745,'valueName': 'Temp', 'value': 3.4, 'units': 'C', 'dateTime': datetime.datetime(2021, 3, 18, 20, 52, 10, tzinfo=<UTC>), 'timestamp': 1616122330.0}]

标签: djangopandaspandas-groupby

解决方案


你可以试试这个:

import pandas as pd

df = pd.DataFrame(
    {
        "hours": [20, 20, 20, 20, 20, 20],
        "minutes": [52, 52, 52, 53, 53, 53],
        "seconds": [10, 30, 35, 0, 5, 10],
    }
)

# Convert values as strings (needed to clear content)
df = df.astype(str)

# Iterate on a copy of the dataframe and modify rows as needed
previous_row = df.iloc[0]
for i, row in df.copy().iterrows():
    if i == 0:
        continue
    if row["minutes"] == previous_row["minutes"]:
        df.loc[i, "minutes"] = ""
        df.loc[i, "hours"] = ""
    previous_row = row

print(df)
#Outputs
  hours minutes seconds
0    20      52      10
1                    30
2                    35
3    20      53       0
4                     5
5                    10

推荐阅读