Pandas - 用空的python dict对象替换DataFrame中的所有NaN值

Val*_*yal 8 python pandas

我有一个pandas DataFrame,其中每个单元格都包含一个python dict.

>>> data = {'Q':{'X':{2:2010}, 'Y':{2:2011, 3:2009}},'R':{'X':{1:2013}}}
>>> frame = DataFrame(data)
>>> frame
                    Q          R
X           {2: 2010}  {1: 2013}
Y  {2: 2011, 3: 2009}        NaN
Run Code Online (Sandbox Code Playgroud)

我想用空的dict替换NaN来获得这个结果:

                    Q          R
X           {2: 2010}  {1: 2013}
Y  {2: 2011, 3: 2009}        {}
Run Code Online (Sandbox Code Playgroud)

但是,因为fillna函数将空字典解释为标量值而不是作为列 - >值的映射,如果我只是这样做(即它不起作用),它就不会这样做:

>>> frame.fillna(inplace=True, value={})
                    Q          R
X           {2: 2010}  {1: 2013}
Y  {2: 2011, 3: 2009}        NaN
Run Code Online (Sandbox Code Playgroud)

有没有办法用来fillna完成我想要的东西?我是否必须遍历整个DataFrame或构建一个愚蠢的dict,并将所有列映射到空dict?

Val*_*yal 11

我能用DataFrame.applymap这种方式:

>>> from pandas import isnull
>>> frame=frame.applymap(lambda x: {} if isnull(x) else x)
>>> frame
                    Q          R
X           {2: 2010}  {1: 2013}
Y  {2: 2011, 3: 2009}         {}
Run Code Online (Sandbox Code Playgroud)

这个解决方案避免了EdChum解决方案中的陷阱(所有NaN单元都指向内存中相同的底层dict对象,阻止它们彼此独立更新)和Shashank(需要使用嵌套构建潜在的大型数据结构) dicts,只是为了指定一个空的dict值).


Jos*_*ode 6

DataFrame.where是一种非常直接实现这一目标的方法:

\n\n
>>> data = {\'Q\': {\'X\': {2: 2010}, \'Y\': {2: 2011, 3: 2009}}, \'R\': {\'X\': {1: 2013}}}\n>>> frame = DataFrame(data)\n>>> frame\n                    Q          R\nX           {2: 2010}  {1: 2013}\nY  {2: 2011, 3: 2009}        NaN\n\n>>> frame.where(frame.notna(), lambda x: [{}])\n                    Q          R\nX           {2: 2010}  {1: 2013}\nY  {2: 2011, 3: 2009}         {}\n
Run Code Online (Sandbox Code Playgroud)\n\n

而且,它似乎更快一点:

\n\n
>>> %timeit frame.where(frame.notna(), lambda x: [{}])\n791 \xc2\xb5s \xc2\xb1 16.3 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000 loops each)\n>>> %timeit frame.applymap(lambda x: {} if isnull(x) else x)\n1.07 ms \xc2\xb1 7.15 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n\n

(在较大的数据集上,我观察到速度提高了约 10 倍)

\n