寻找更好的迭代方法来切片数据框
looking for better iteration approach for slicing a dataframe
首先 post:我提前为草率的措辞道歉(如果这个问题在其他地方得到了令人作呕的回答,可能搜索不当——也许我还不知道正确的搜索词)。
我有 10 分钟的数据块,我想对按分钟分组的列 ('input') 执行计算(即 10 个独立的 60 秒块 - 而不是滚动的 60 秒周期)然后将所有十个计算存储在一个名为输出的列表中。
'seconds'栏记录10分钟内从1到600的秒数。如果给定秒内没有输入数据,则该秒数没有行。所以,有些分钟有 60 行数据,有些只有一两行。
注意:计算 (my_function) 不是基本的,所以我不能使用 groupby 和 np.sum()、np.mean() 等 - 或者至少我不知道如何使用 groupby。
我有可以完成工作的代码,但对我来说它看起来很丑,所以我确信有更好的方法(可能有几种)。
output=[]
seconds_slicer = 0
for i in np.linspace(1,10,10):
seconds_slicer += 60
minute_slice = df[(df['seconds'] > (seconds_slicer - 60)) &
(df['seconds'] <= seconds_slicer)]
calc = my_function(minute_slice['input'])
output.append(calc)
如果有更简洁的方法,请告诉我。谢谢!
编辑:添加示例数据和函数详细信息:
seconds input
1 1 0.000054
2 2 -0.000012
3 3 0.000000
4 4 0.000000
5 5 0.000045
def realized_volatility(series_log_return):
return np.sqrt(np.sum(series_log_return**2))
对于这个答案,我们将重新调整用途 Bin pandas dataframe by every X rows
我们将在 'seconds' 列中创建一个缺少数据的数据框,据我所知,您的数据将基于给定的描述
secs=[1,2,3,4,5,6,7,8,9,11,12,14,15,17,19]
data = [np.random.randint(-25,54)/100000 for _ in range(15)]
df=pd.DataFrame(data=zip(secs,data), columns=['seconds','input'])
df
seconds input
0 1 0.00017
1 2 -0.00020
2 3 0.00033
3 4 0.00052
4 5 0.00040
5 6 -0.00015
6 7 0.00001
7 8 -0.00010
8 9 0.00037
9 11 0.00050
10 12 0.00000
11 14 -0.00009
12 15 -0.00024
13 17 0.00047
14 19 -0.00002
我没有创建 600 行,但没关系,我们会说我们想要每 5 秒而不是每 60 秒装箱。现在,因为我们只是尝试使用相等的时间度量来分组,我们可以只使用 floor division 来查看每个时间间隔 会 最终进入哪个 bin。(在你的情况下,你将除以 60)
grouped=df.groupby(df['seconds'] // 5).apply(realized_volatility).drop('seconds', axis=1) #we drop the extra 'seconds' column because we don;t care about the root sum of squares of seconds in the df
grouped
input
seconds
0 0.000441
1 0.000372
2 0.000711
3 0.000505
首先 post:我提前为草率的措辞道歉(如果这个问题在其他地方得到了令人作呕的回答,可能搜索不当——也许我还不知道正确的搜索词)。
我有 10 分钟的数据块,我想对按分钟分组的列 ('input') 执行计算(即 10 个独立的 60 秒块 - 而不是滚动的 60 秒周期)然后将所有十个计算存储在一个名为输出的列表中。
'seconds'栏记录10分钟内从1到600的秒数。如果给定秒内没有输入数据,则该秒数没有行。所以,有些分钟有 60 行数据,有些只有一两行。
注意:计算 (my_function) 不是基本的,所以我不能使用 groupby 和 np.sum()、np.mean() 等 - 或者至少我不知道如何使用 groupby。
我有可以完成工作的代码,但对我来说它看起来很丑,所以我确信有更好的方法(可能有几种)。
output=[]
seconds_slicer = 0
for i in np.linspace(1,10,10):
seconds_slicer += 60
minute_slice = df[(df['seconds'] > (seconds_slicer - 60)) &
(df['seconds'] <= seconds_slicer)]
calc = my_function(minute_slice['input'])
output.append(calc)
如果有更简洁的方法,请告诉我。谢谢!
编辑:添加示例数据和函数详细信息:
seconds input
1 1 0.000054
2 2 -0.000012
3 3 0.000000
4 4 0.000000
5 5 0.000045
def realized_volatility(series_log_return):
return np.sqrt(np.sum(series_log_return**2))
对于这个答案,我们将重新调整用途 Bin pandas dataframe by every X rows
我们将在 'seconds' 列中创建一个缺少数据的数据框,据我所知,您的数据将基于给定的描述
secs=[1,2,3,4,5,6,7,8,9,11,12,14,15,17,19]
data = [np.random.randint(-25,54)/100000 for _ in range(15)]
df=pd.DataFrame(data=zip(secs,data), columns=['seconds','input'])
df
seconds input
0 1 0.00017
1 2 -0.00020
2 3 0.00033
3 4 0.00052
4 5 0.00040
5 6 -0.00015
6 7 0.00001
7 8 -0.00010
8 9 0.00037
9 11 0.00050
10 12 0.00000
11 14 -0.00009
12 15 -0.00024
13 17 0.00047
14 19 -0.00002
我没有创建 600 行,但没关系,我们会说我们想要每 5 秒而不是每 60 秒装箱。现在,因为我们只是尝试使用相等的时间度量来分组,我们可以只使用 floor division 来查看每个时间间隔 会 最终进入哪个 bin。(在你的情况下,你将除以 60)
grouped=df.groupby(df['seconds'] // 5).apply(realized_volatility).drop('seconds', axis=1) #we drop the extra 'seconds' column because we don;t care about the root sum of squares of seconds in the df
grouped
input
seconds
0 0.000441
1 0.000372
2 0.000711
3 0.000505