pandas:在 DataFrame 中记录单元格时有效避免 0

Dus*_*els 4 python pandas

我想在一个非常稀疏的 pandas DataFrame 中获取每个单元格的日志,并且必须避免 0。起初我用 lambda 函数检查 0,然后我认为用 NaN 替换许多 0 可能会更快。我从这个密切相关的问题中得到了一些灵​​感,并尝试使用“面具”。有没有更好的办法?

\n\n
# first approach\n# 7.61 s \xc2\xb1 1.46 s per loop (mean \xc2\xb1 std. dev. of 7 runs, 1 loop each)\ndef get_log_1(df):\n    return df.applymap(\n        lambda x: math.log(x) if x != 0 else 0)\n\n# second approach (faster!)\n# 5.36 s \xc2\xb1 968 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 1 loop each)\ndef get_log_2(df):\n    return (df\n            .replace(0, np.nan)\n            .applymap(math.log)\n            .replace(np.nan, 0))\n\n# third apprach (even faster!!)\n# 4.76 s \xc2\xb1 941 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 1 loop each)\ndef get_log_3(df):\n    return (df\n            .mask(df <= 0)\n            .applymap(math.log)\n            .fillna(0))\n
Run Code Online (Sandbox Code Playgroud)\n\n\n

jez*_*ael 6

一种可能的解决方案是使用numpy.log

print (np.log(df.mask(df <=0)).fillna(0))
Run Code Online (Sandbox Code Playgroud)

或纯numpy

df1= pd.DataFrame(np.ma.log(df.values).filled(0), index=df.index, columns=df.columns)
Run Code Online (Sandbox Code Playgroud)

  • 第一种方式为 341 ms ± 7.08 ms,第二种方式为 35.6 ns ± 5.57 ns(使用 Ipython `%timeit` 魔法测量) (2认同)