熊猫 df 迭代,基于时间(以毫秒为单位)的数据分箱

panda df iteration, binning of data based on time in milliseconds

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

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

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

(3) 因此,在我按 'data2' 和 'time' 对数据进行分组后,我需要在预定义的时间间隔内(即 [0=10ms)、[10- 20ms) 等),因此第 0、1、2 行将落在 [0-10ms) bin 下,例如。因此,我需要能够首先定义这些箱子(我将有一组固定的箱子)。然后,对于下一个 'data2' 更改(例如,从 55 到 56),我们将开始时间设置为 0,并根据从 0 到 data2 再次更改所经过的时间对行数据进行分类。等等。我该如何编写代码,我最费劲的地方是将计时器设置为“0”并在 'data2' 值未更改的情况下为每一行引用 'time'。然后当 '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

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 毫秒。