如何加速pandas申请?
How to speed up pandas apply?
我有一个包含 314 万行的大型 DataFrame,我需要使用 1 列对它们进行分组,然后按组计算标准差和均值。我已经完成了以下操作并且它按预期工作,但它非常慢(仅 20000 行就需要 1 分钟以上)。我很确定有更快的方法,但是当我尝试 google.
时找不到任何方法
def gen_time_feats(df):
feats = df.loc[:, 'f_0':'f_299']
for col in feats.columns:
df[f'{col}_avg'] = np.mean(feats[col].values)
df[f'{col}_std'] = np.std(feats[col].values)
return df
df_grouped = df.groupby('group_id')
df_with_time_feat = df_grouped.apply(gen_time_feats)
DataFrame 有 300 列,我想为每一列附加 std dev 和 mean 作为附加列,所以最后它会变成 900 列。
使用 filter
到 select f_xxx
列然后 groupby
group_id
列然后使用函数列表应用于每个列。最后,平整你的列索引。
out = df.filter(regex='f_\d+').groupby(df['group_id']).agg(['mean', 'std'])
out.columns = out.columns.to_flat_index().str.join('_')
out = df.set_index('group_id').join(out).sort_index(axis=1).reset_index()
print(out)
# Output:
group_id f_100 f_100_mean f_100_std f_200 f_200_mean f_200_std
0 A 1 3.0 2.828427 5 7.0 2.828427
1 A 5 3.0 2.828427 9 7.0 2.828427
2 B 2 3.0 1.414214 6 7.0 1.414214
3 B 4 3.0 1.414214 8 7.0 1.414214
设置:
df = pd.DataFrame({'group_id': list('ABBA'), 'f_100': [1, 2, 4, 5], 'f_200': [5, 6, 8, 9]})
print(df)
# Output
group_id f_100 f_200
0 A 1 5
1 B 2 6
2 B 4 8
3 A 5 9
请注意,如果您想使用名称“_avg”而不是“_mean”,请使用 agg
的修改版本:.agg([('avg', 'mean'), 'std'])
我认为这是最简单的。在我的 PC 上,table 有 314 万行需要大约 16 秒。
desc = pd.merge(df.groupby("group_id").mean(),
df.groupby("group_id").std(ddof=0),
suffixes=("_avg", "_std"), left_index=True, right_index=True)
# print(desc) # This table contains mean and std for each group.
result = df.merge(desc.reset_index(), on='group_id')
我有一个包含 314 万行的大型 DataFrame,我需要使用 1 列对它们进行分组,然后按组计算标准差和均值。我已经完成了以下操作并且它按预期工作,但它非常慢(仅 20000 行就需要 1 分钟以上)。我很确定有更快的方法,但是当我尝试 google.
时找不到任何方法def gen_time_feats(df):
feats = df.loc[:, 'f_0':'f_299']
for col in feats.columns:
df[f'{col}_avg'] = np.mean(feats[col].values)
df[f'{col}_std'] = np.std(feats[col].values)
return df
df_grouped = df.groupby('group_id')
df_with_time_feat = df_grouped.apply(gen_time_feats)
DataFrame 有 300 列,我想为每一列附加 std dev 和 mean 作为附加列,所以最后它会变成 900 列。
使用 filter
到 select f_xxx
列然后 groupby
group_id
列然后使用函数列表应用于每个列。最后,平整你的列索引。
out = df.filter(regex='f_\d+').groupby(df['group_id']).agg(['mean', 'std'])
out.columns = out.columns.to_flat_index().str.join('_')
out = df.set_index('group_id').join(out).sort_index(axis=1).reset_index()
print(out)
# Output:
group_id f_100 f_100_mean f_100_std f_200 f_200_mean f_200_std
0 A 1 3.0 2.828427 5 7.0 2.828427
1 A 5 3.0 2.828427 9 7.0 2.828427
2 B 2 3.0 1.414214 6 7.0 1.414214
3 B 4 3.0 1.414214 8 7.0 1.414214
设置:
df = pd.DataFrame({'group_id': list('ABBA'), 'f_100': [1, 2, 4, 5], 'f_200': [5, 6, 8, 9]})
print(df)
# Output
group_id f_100 f_200
0 A 1 5
1 B 2 6
2 B 4 8
3 A 5 9
请注意,如果您想使用名称“_avg”而不是“_mean”,请使用 agg
的修改版本:.agg([('avg', 'mean'), 'std'])
我认为这是最简单的。在我的 PC 上,table 有 314 万行需要大约 16 秒。
desc = pd.merge(df.groupby("group_id").mean(),
df.groupby("group_id").std(ddof=0),
suffixes=("_avg", "_std"), left_index=True, right_index=True)
# print(desc) # This table contains mean and std for each group.
result = df.merge(desc.reset_index(), on='group_id')