我有一个熊猫数据框,我想基于一些short_window
,long_window
和bins
值来计算一些特征。更具体地说,对于每个不同的行,我想计算一些特征。为此,我将df_long = df.loc[row:long_window+row]
向前移动了一行,例如在第一次迭代中,row=0
的熊猫数据帧将为df_long = df.loc[0:50+0]
,并将根据此数据计算一些特征帧,则row=1
将是df_long = df.loc[1:50+1]
,其他一些特征将被计算并继续。
from numpy.random import seed
from numpy.random import randint
import pandas as pd
from joblib import Parallel, delayed
bins = 12
short_window = 10
long_window = 50
# seed random number generator
seed(1)
price = pd.DataFrame({
'DATE_TIME': pd.date_range('2012-01-01', '2012-02-01', freq='30min'),
'value': randint(2, 20, 1489),
'amount': randint(50, 200, 1489)
})
def vap(row, df, short_window, long_window, bins):
df_long = df.loc[row:long_window+row]
df_short = df_long.tail(short_window)
binning = pd.cut(df_long['value'], bins, retbins=True)[1]
group_months = pd.DataFrame(df_short['amount'].groupby(pd.cut(df_short['value'], binning)).sum())
return group_months['amount'].tolist(), df.loc[long_window + row + 1, 'DATE_TIME']
def feature_extraction(data, short_window, long_window, bins):
# Vap feature extraction
ls = [f"feature{row + 1}" for row in range(bins)]
amount, date = zip(*Parallel(n_jobs=4)(delayed(vap)(i, data, short_window, long_window, bins)
for i in range(0, data.shape[0] - long_window - 1)))
temp = pd.DataFrame(date, columns=['DATE_TIME'])
temp[ls] = pd.DataFrame(amount, index=temp.index)
data = data.merge(temp, on='DATE_TIME', how='outer')
return data
df = feature_extraction(price, short_window, long_window, bins)
为了节省时间,我尝试并行运行它,但是由于我的数据量大,需要很长时间才能完成。
是否有任何方法可以更改此迭代过程(df_long = df.loc[row:long_window+row])
以降低计算成本?我想知道是否有任何方法可以使用pandas.rolling,但是我不确定在这种情况下如何使用它。
任何帮助将不胜感激! 谢谢
答案 0 :(得分:0)
这是第一次尝试加快计算速度。我检查了前100行,发现binning变量始终相同。所以我设法用固定的垃圾箱做一个高效的算法。但是,当我检查整个数据的功能时,我发现1489中大约有100行,它们具有不同的装箱变量,因此下面的解决方案与原始答案有100行的差异。
基准化:
我的快速功能:28毫秒
我的精确功能:388毫秒
原始功能:12200毫秒
因此,快速功能的速度提高了约500倍,精确功能的速度提高了20倍
快速功能代码:
def feature_extraction2(data, short_window, long_window, bins):
ls = [f"feature{row + 1}" for row in range(bins)]
binning = pd.cut([2,19], bins, retbins=True)[1]
bin_group = np.digitize(data['value'], binning, right=True)
l_sum = []
for i in range(1, bins+1):
sum1 = ((bin_group == i)*data['amount']).rolling(short_window).sum()
l_sum.append(sum1)
ar_sum = np.array(l_sum).T
ar_shifted = np.empty_like(ar_sum)
ar_shifted[:long_window+1,:] = np.nan
ar_shifted[long_window+1:,:] = ar_sum[long_window:-1,:]
temp = pd.DataFrame(ar_shifted, columns = ls)
data = pd.concat([data,temp], axis = 1, sort = False)
return data
精确功能:
data = price.copy()
# Vap feature extraction
ls = [f"feature{row + 1}" for row in range(bins)]
data.shape[0] - long_window - 1)))
norm_volume = []
date = []
for i in range(0, data.shape[0] - long_window - 1):
row = i
df = data
df_long = df.loc[row:long_window+row]
df_short = df_long.tail(short_window)
binning = pd.cut(df_long['value'], bins, retbins=True)[1]
group_months = df_short['amount'].groupby(pd.cut(df_short['value'], binning)).sum().values
x,y = group_months, df.loc[long_window + row + 1, 'DATE_TIME']
norm_volume.append(x)
date.append(y)
temp = pd.DataFrame(date, columns=['DATE_TIME'])
temp[ls] = pd.DataFrame(norm_volume, index=temp.index)
data = data.merge(temp, on='DATE_TIME', how='outer')