【问题标题】:panda df iteration, binning of data based on time in millisecondspanda df 迭代,基于时间的数据分箱(以毫秒为单位)
【发布时间】:2020-06-04 18:34:44
【问题描述】:

我重新调整了我的问题的重点,并尝试尽可能具体。下面,我还包括我目前使用的代码;

(1) 从 SQL 中提取数据时,我的时间是混合格式,其中包含一个难以处理的字母。为避免出现问题,我尝试申请; df.time=pd.to_timedelta(df.time, unit='ms'),这很好,因为不知道如何提取小时和分钟。示例;2019.11.22D01:18:00.01000,我只需要以下格式的“时间”列; '01:18:00.01000'。也许我可以使用“np.datetime64”将我所有的 SQL 时间条目转换为所需的格式并截断我需要的字符数量?请告知团队。我也试过 'data=np.datetime64('time') 但是得到 ' Error parsing datetime string "time" at position 0 '。

(2) 我试图将我的数据按 2 个因素分组,首先是“data2”,然后是“时间”。这是因为我的数据不会按以下顺序排列,而是按随机顺序排列。我得到:“DataFrameGroupBy”不可调用。那是因为我有重复的 data2 值吗?请您帮忙看看是什么原因造成的?

(3) 因此,在我将数据按“data2”和“时间”分组后,我需要在预定义的时间间隔内(即 [0=10ms)、[10-20ms)等)对数据进行分类,所以例如,第 0,1,2 行将属于 [0-10ms) 箱。因此,我需要能够首先定义这些垃圾箱(我将拥有一组固定的垃圾箱)。然后,对于下一个“data2”更改(例如,从 55 到 56),我们将开始时间设置为 0,并根据从 0 到 data2 再次更改所经过的时间对行数据进行分类。等等。我该如何编码,我最挣扎的地方是将计时器设置为“0”并为每一行引用“时间”,只要“data2”值没有改变。然后当“data2”发生变化时,重新开始,相应地对数据进行分箱。

下面是我目前使用的代码;

import pyodbc 
import pandas as pd
import numpy as np

conn = pyodbc.connect('Driver={SQL Server};'
                      'Server=XXXXXXXXX;'
                      'Database=Dynamics;'
                      'Trusted_Connection=yes;')

cursor = conn.cursor()

SQL_Query = pd.read_sql_query('''select ID,time,data1,data2,data3,data4,data5 from Dynamics''', conn)
df = pd.DataFrame(SQL_Query, columns=['ID','time','data2','data3','data4','data5'])
df.time=pd.to_timedelta(df.time, unit='ms')
df[['data4']] = df[['data4']].apply(pd.to_numeric)
df['diff']=df['data4']-df['data5']
df['diff']=df['diff'].abs()
df=df.groupby(['data3','time'])
print(df)



                     time data_1  data_2 data_3  data_4  data_5
0 2019-11-22 01:18:00.010      a      55      A    1.20    1.24
1 2019-11-22 01:18:00.090      a      55      B    1.25    1.24
2 2019-11-22 01:18:00.100      a      55      C    1.26    1.24
3 2019-11-22 01:18:00.140      a      55      A    1.22    1.22
4 2019-11-22 01:18:00.160      a      55      B    1.23    1.22

【问题讨论】:

  • 欢迎来到 StackOverflow。如果您到目前为止发布代码并向我们展示出了什么问题,那么您更容易得到响应。还请包含 Python 代码以在您的图像中重新创建列,因为 1)我们中的一些人看不到图像,并且 2)让我们重新创建您的列是一种负担。
  • 添加了一些 Python,应该可以更轻松地重现您的初始数据帧。您可能想查看 stackoverflow.com/questions/43500894/…stackoverflow.com/questions/52426972/… 以了解如何将日期时间分组到 bin 中的示例。
  • @rajah9 非常感谢您的建议,它提供了一些很好的指导,所以我现在重新调整了我的问题,使其更加具体,并包含了我迄今为止编写的代码。谢谢大家的帮助! (为了简单起见,我已经调整了我最初问题的内容,并试图尽可能具体)。
  • @rajah9 - 太好了,我已经在处理您的建议并获得一些有意义的结果。非常感谢!

标签: python pandas loops dataframe binning


【解决方案1】:

Pandas 有一个很棒的日期范围功能。这是一个创建一分钟范围的示例,每行都有一个新的毫秒(这也是索引)。

import pandas as pd
from datetime import timedelta
import numpy as np

date_rng = pd.date_range(start='2019-11-22T01:18:00.00100', end='2019-11-22T01:19:00.00000', freq='ms') #one minute, in milliseconds
n = len(date_rng) # n = 60000
values = np.random.random(n) # make n random numbers

df = pd.DataFrame({'values': values}, index=date_rng)
print ('dataframe: ')
print (df.head())

这是df的头:

dataframe: 
                           values
2019-11-22 01:18:00.001  0.914796
2019-11-22 01:18:00.002  0.760555
2019-11-22 01:18:00.003  0.132992
2019-11-22 01:18:00.004  0.572391
2019-11-22 01:18:00.005  0.090188

接下来,Pandas 有一个很好的重采样功能,在本例中,它对 10 毫秒 bin 中的值求和。

df2 = df.resample(rule=timedelta(milliseconds=10)).sum() # df2 sums the values in 10 ms bins
print ('beginning of df2')
print (df2.head())
print ('...')
print (df2.tail())

这是输出:

beginning of df2
                           values
2019-11-22 01:18:00.000  5.236037
2019-11-22 01:18:00.010  4.446964
2019-11-22 01:18:00.020  6.549635
2019-11-22 01:18:00.030  5.141522
2019-11-22 01:18:00.040  5.375919
...
                           values
2019-11-22 01:18:59.960  3.876523
2019-11-22 01:18:59.970  4.864252
2019-11-22 01:18:59.980  5.690987
2019-11-22 01:18:59.990  2.787247
2019-11-22 01:19:00.000  0.613545

请注意,最后一个值要小得多,因为仅表示 1 ms。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    相关资源
    最近更新 更多