我有一个时间序列列表(= pandas数据帧),并想为(设备的)每个时间序列计算matrixprofile。 一种选择是迭代所有设备-这似乎很慢。 第二种选择是按设备分组-并应用UDF。现在的问题是,UDF将返回1:1行,即不是每组一个标量值,而是将输出相同数量的行作为输入。
返回1:1(或至少是非标量值)后,是否仍可以某种方式对覆盖范围组的计算进行矢量化处理?
import pandas as pd
df = pd.DataFrame({
'foo':[1,2,3], 'baz':[1.1, 0.5, 4], 'bar':[1,2,1]
})
display(df)
print('***************************')
# slow version retaining all the rows
for g in df.bar.unique():
print(g)
this_group = df[df.bar == g]
# perform a UDF which needs to have all the values per group
# i.e. for real I want to calculate the matrixprofile for each time-series of a device
this_group['result'] = this_group.baz.apply(lambda x: 1)
display(this_group)
print('***************************')
def my_non_scalar1_1_agg_function(x):
display(pd.DataFrame(x))
return x
# neatly vectorized application of a non_scalar function
# but this fails as: Must produce aggregated value
df = df.groupby(['bar']).baz.agg(my_non_scalar1_1_agg_function)
display(df)
答案 0 :(得分:1)
对于应用于不返回非标量值的每个不同组的非聚合函数,您需要跨组迭代方法,然后一起编译。
因此,考虑使用groupby()
,后跟concat
的列表或字典理解。确保方法输入并返回完整的数据框,序列或ndarray。
# LIST COMPREHENSION
df_list = [ myfunction(sub) for index, sub in df.groupby(['group_column']) ]
final_df = pd.concat(df_list)
# DICT COMPREHENSION
df_dict = { index: myfunction(sub) for index, sub in df.groupby(['group_column']) }
final_df = pd.concat(df_dict, ignore_index=True)
答案 1 :(得分:0)
实际上,这是一种使它以更快/更理想的方式工作的方法(另请参见注释中的链接)。也许还有更好的选择
import pandas as pd
df = pd.DataFrame({
'foo':[1,2,3], 'baz':[1.1, 0.5, 4], 'bar':[1,2,1]
})
display(df)
grouped_df = df.groupby(['bar'])
altered = []
for index, subframe in grouped_df:
display(subframe)
subframe = subframe# obviously we need to apply the UDF here - not the idempotent operation (=doing nothing)
altered.append(subframe)
print (index)
#print (subframe)
pd.concat(altered, ignore_index=True)
#pd.DataFrame(altered)