熊猫 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 毫秒。
我重新调整了我的问题并尝试尽可能具体。下面,我还包括我到目前为止使用的代码;
(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 毫秒。