我有一个大型DF,具有17520行和1000列。 df只有两个值[0,0.05]。我想转到值为0.05的df的每个单元格,并将其更改为随机值。随机值只能是0或0.05。
我尝试了以下代码行:
y = np.array([0,0.05])
df.replace(0.05,np.random.choice(y))
但是,它对所有值为0.05的单元格执行相同的随机选择,我希望为每个值为0.05的单元格执行不同的随机选择。我尝试了for循环,但是这花费了太多时间,大约需要20分钟。我需要重复进行约100次实验。
出于这个原因,我想知道是否有一种更有效的方法。
感谢您的帮助。
答案 0 :(得分:1)
代替循环,您可以像这样使用df.update()
来使速度提高20倍以上:
df = pd.DataFrame(np.random.choice([0, 0.05], size=(4000, 1000)))
%timeit df.update(np.random.choice([0, 0.05], size=df.shape), filter_func=lambda x: x==0.05)
#498 ms ± 19.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
df = pd.DataFrame(np.random.choice([0, 0.05], size=(4000, 1000)))
%timeit df.applymap(lambda x: np.random.choice([0, 0.05]) if x == 0.05 else 0)
#9.66 s ± 634 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
我注意到,提速只是在越来越大的数据帧上才有所提高,但是在这里applymap花费了很长时间,因此我决定不再进一步增加DataFrame的大小。
df = pd.DataFrame(np.random.choice([0, 0.05], size=(1000, 1000)))
print(df.tail(2))
df.update(np.random.choice([0, 0.05], size=df.shape), filter_func=lambda x: x==0.05)
print(df.tail(2))
# 0 1 2 3 4 5 ... 994 995 996 997 998 999
#998 0.00 0.05 0.05 0.0 0.05 0.05 ... 0.0 0.05 0.05 0.05 0.05 0.0
#999 0.05 0.00 0.05 0.0 0.05 0.05 ... 0.0 0.05 0.05 0.05 0.00 0.0
#
#[2 rows x 1000 columns]
# 0 1 2 3 4 5 ... 994 995 996 997 998 999
#998 0.00 0.05 0.00 0.0 0.05 0.05 ... 0.0 0.05 0.05 0.0 0.05 0.0
#999 0.05 0.00 0.05 0.0 0.05 0.00 ... 0.0 0.00 0.05 0.0 0.00 0.0
#
#[2 rows x 1000 columns]
使用update
,您可以更改DataFrame中的选定值。要选择值(默认值np.nan
),请使用filter_func= lambda x: x==0.05
,然后创建一个大小与原始DataFrame相同的DataFrame,并从[0, 0.05]
中随机选择。然后,它从值为0.05
的原始DataFrame中选择值,并将其替换为随机vlaue。