仅使用每行之前的行数据对 DataFrame 的操作进行向量化

问题描述 投票:0回答:1

有没有一种方法可以向量化 pandas 的 DataFrame 行操作,以仅使用前一行数据进行计算,而不使用 python 级别的迭代?

我正在尝试计算每行上给定分布的分位数,但我想避免数据泄漏。

因此,对于每一行,我想计算

sequence[:current_row]
的分位数。

import pandas as pd

import numpy as np

test_df = pd.DataFrame({'column_1':np.random.random(10)})

qtls = pd.DataFrame({'q1':[],
                     'q2':[],
                     'q3':[],
                     'q4':[],
                     'q5':[],
                     'q6':[],
                     'q7':[],
                     'q8':[],
                     'q9':[]})
for i in range(1,len(test_df)+1):
    qtls = pd.concat([qtls, pd.DataFrame({k:[v] for k,v in zip(['q'+str(j) for j in range(1, 10)], np.quantile(test_df['column_1'].iloc[:i], np.arange(0.1,1.0,0.1)))})])
qtls = qtls.reset_index(drop=True)

test_df = pd.concat([test_df, qtls], axis=1)

test_df

这就是 for 循环的暴力实现。

这是预期的结果:

索引 第_1栏 q1 q2 q3 q4 q5 q6 q7 q8 q9
0 0.913871 0.913871 0.913871 0.913871 0.913871 0.913871 0.913871 0.913871 0.913871 0.913871
1 0.374344 0.428297 0.482249 0.536202 0.590155 0.644107 0.698060 0.752013 0.805966 0.859918
2 0.886332 0.476741 0.579139 0.681536 0.783934 0.886332 0.891840 0.897347 0.902855 0.908363
3 0.499623 0.411928 0.449511 0.487095 0.576965 0.692977 0.808990 0.889086 0.897347 0.905609
4 0.516991 0.424455 0.474567 0.503097 0.510044 0.516991 0.664727 0.812463 0.891840 0.902855
5 0.788121 0.436983 0.499623 0.508307 0.516991 0.652556 0.788121 0.837226 0.886332 0.900101
6 0.180458 0.296789 0.399400 0.474567 0.506570 0.516991 0.679669 0.807763 0.866689 0.897347
7 0.726476 0.316178 0.424455 0.501360 0.513517 0.621734 0.738805 0.781956 0.847047 0.894593
8 0.142783 0.172923 0.296789 0.424455 0.503097 0.516991 0.684579 0.763463 0.827405 0.891840
9 0.844354 0.176690 0.335567 0.462039 0.510044 0.621734 0.751134 0.804991 0.852750 0.889086

怎样才能高效地做到这一点?

如果有一个

df['some_column'] = df['another_column'].cumquantile()
不是很容易吗?

python pandas dataframe numpy vectorization
1个回答
0
投票

我认为你不能真正对其进行矢量化,但你可以将你的代码简化为:

np.random.seed(0)
test_df = pd.DataFrame({'column_1':np.random.random(10)})

q = test_df['column_1'].expanding().quantile

out = test_df.join(pd.DataFrame({f'q{i}': q(x) for i, x in
                                 enumerate(np.arange(0.1,1.0,0.1), start=1)}))

但是应该会更快,因为它不再循环运行

concat

输出:

   column_1        q1        q2        q3        q4        q5        q6        q7        q8        q9
0  0.548814  0.548814  0.548814  0.548814  0.548814  0.548814  0.548814  0.548814  0.548814  0.548814
1  0.715189  0.565451  0.582089  0.598726  0.615364  0.632001  0.648639  0.665277  0.681914  0.698552
2  0.602763  0.559603  0.570393  0.581183  0.591973  0.602763  0.625249  0.647734  0.670219  0.692704
3  0.544883  0.546062  0.547241  0.548420  0.559603  0.575788  0.591973  0.614006  0.647734  0.681462
4  0.423655  0.472146  0.520638  0.545669  0.547241  0.548814  0.570393  0.591973  0.625249  0.670219
5  0.645894  0.484269  0.544883  0.546848  0.548814  0.575788  0.602763  0.624329  0.645894  0.680542
6  0.437587  0.432014  0.459046  0.523424  0.546455  0.548814  0.581183  0.611390  0.637268  0.673612
7  0.891773  0.433407  0.480506  0.545276  0.548027  0.575788  0.611390  0.641581  0.687471  0.768164
8  0.963663  0.434801  0.501965  0.546455  0.559603  0.602763  0.637268  0.687471  0.785823  0.906151
9  0.383442  0.419633  0.434801  0.512694  0.547241  0.575788  0.620016  0.666683  0.750506  0.898962
© www.soinside.com 2019 - 2024. All rights reserved.