pandas 哪一个更好?np.where还是.loc?

iecba09b  于 2023-02-11  发布在  其他
关注(0)|答案(3)|浏览(193)

我发现了两种基于条件替换 Dataframe 中某些值的形式:
1..位置

mask = df['param'].isnull()
df.loc[mask, 'param'] = 'new_value'

1.名词,其中()

mask = df['param'].isnull()
df['param'] = np.where(mask, 'new_value', df['param'])

这两种形式都很好用,但是哪一种更好呢?关于这个问题,什么时候应该使用**.loc**,什么时候应该使用np.where

neskvpey

neskvpey1#

这不是一个贯穿测试,但这里有一个样本,在每次运行(locnp.where)时,数据都被重置为原始的随机数。

玩具数据1

这里的np.nan超过了有效值。而且,该列是float类型。

np.random.seed(1)
df = pd.DataFrame({'param': np.random.choice((1, np.nan), 1000000, p=(0.3,0.7))})

# loc
%%timeit
mask = df['param'].isnull()
df.loc[mask, 'param'] = 'new_value'
# 46.7 ms ± 177 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

# np.where
%%timeit
mask = df['param'].isnull()
df['param'] = np.where(mask, 'new_value', df['param'])
# 86.8 ms ± 2.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

玩具资料二:

这里的np.nan小于有效值,并且列为对象类型:

np.random.seed(1)
df = pd.DataFrame({'param': np.random.choice(("1", np.nan), 1000000, p=(0.7,0.3))})

同样的故事:

df.loc[mask, 'param'] = 'new_value'
# 47.8 ms ± 350 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

df['param'] = np.where(mask, 'new_value', df['param'])
# 58.9 ms ± 1.72 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

因此,与@cs95的评论相反,loc似乎优于np.where

yyyllmsg

yyyllmsg2#

值得一提的是,我正在处理一个非常大的数据集(数百万行,100+列),我使用df.loc进行简单的替换,通常需要几个小时。当我更改为np.where时,它立即工作。

2exbekwf

2exbekwf3#

代码在jupyter笔记本中运行

np.random.seed(42)
df1 = pd.DataFrame({'a':np.random.randint(0, 10, 10000)})

%%timeit
df1["a"] = np.where(df1["a"] == 2, 8, df1["a"])
# 163 µs ± 3.47 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

%%timeit
df1.loc[df1['a']==2,'a'] = 8
# 203 µs ± 2.68 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

%%timeit
df1.loc[np.where(df1.a.values==2)]['a'] = 8
# 383 µs ± 9.44 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
# I have a question about this, Why does df1.loc[np.where(df1.a.values==2), 'a']= 8 report an error

%%timeit
df1.iloc[np.where(df1.a.values==2),0] = 8
# 101 µs ± 870 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

我有一个关于第三种编写方式的问题,为什么df1.loc[np.where(df1.a.values==2),'a']= 8报告错误

相关问题