我有一个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
我想用空的dict替换NaN,以获得这个结果:
Q R
X {2: 2010} {1: 2013}
Y {2: 2011, 3: 2009} {}
但是,因为fillna
函数将空字典解释为标量值而不是列的映射 - >价值,如果我只是这样做就没有了(即它不起作用):
>>> frame.fillna(inplace=True, value={})
Q R
X {2: 2010} {1: 2013}
Y {2: 2011, 3: 2009} NaN
有没有办法使用fillna
来实现我的目标?
我是否必须遍历整个DataFrame或构建一个愚蠢的字典,并将所有列映射到空字典?
答案 0 :(得分:10)
我能够以这种方式使用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} {}
这个解决方案避免了EdChum解决方案中的陷阱(所有NaN单元都指向内存中相同的底层dict对象,阻止它们彼此独立更新)和Shashank(需要潜在的大型数据结构)用嵌套的dicts构造,只是为了指定一个空的dict值。)
答案 1 :(得分:2)
这可以使用loc
:
In [6]:
frame.loc[frame['R'].isnull(), 'R'] = {}
frame
Out[6]:
Q R
X {2: 2010} {1: 2013}
Y {2: 2011, 3: 2009} {}
答案 2 :(得分:2)
问题是当dict传递给fillna
时,它会尝试根据框架中的列填充值。所以我尝试的第一个解决方案是 -
frame.fillna({column: {} for column in frame.columns})
但是如果在这样的第二级提供字典,它会尝试将键与索引匹配,因此有效的解决方案是 -
frame.fillna({column: {ind: {} for ind in frame.index} for column in frame.columns})
哪个给出 -
Q R
X {2: 2010} {1: 2013}
Y {2: 2011, 3: 2009} {}
EdChum的答案可能更适合您的需求,但是当您不想进行更改时,可以使用此答案。
编辑:上面的解决方案适用于较小的帧,但对于较大的帧可能是一个问题。使用replace
可以解决这个问题。
frame.replace(np.nan, {column: {} for column in frame.columns})
答案 3 :(得分:0)
使用#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
unsigned int code = 0;
FILE *fp;
fp = fopen(argv[1], "r+");
int result = fscanf(fp, "%x", &code);
printf("\n hex-1: %08X, decimal-1: %d \n", code, code);
printf("\n%x\n", code >>26);
printf("\n%x\n", code >>21 & 0x0b00000011111); //what can i do to change this
while (result != EOF)
{
result = fscanf(fp, "%x", &code);
printf("\n read hex: %08X, decimal: %d \n", code, code);
if(feof(fp))
{
puts("EOF");
break;
}//if
}//while
}
访问器直接分配到numpy数组:
.values
答案 4 :(得分:0)
DataFrame.where
是一种非常直接的实现此目的的方法:
>>> 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
>>> frame.where(frame.notna(), lambda x: [{}])
Q R
X {2: 2010} {1: 2013}
Y {2: 2011, 3: 2009} {}
而且,它似乎更快一些:
>>> %timeit frame.where(frame.notna(), lambda x: [{}])
791 µs ± 16.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
>>> %timeit frame.applymap(lambda x: {} if isnull(x) else x)
1.07 ms ± 7.15 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
(在较大的数据集上,我观察到速度提高了约10倍)
答案 5 :(得分:0)
@Josh_Bode 的回答对我帮助很大。这是一个略有不同的版本。我使用了 mask() 而不是 where() (非常微不足道的变化)。我还更新了分配空字典的方式。通过创建一个与框架一样长的 dict 实例列表,然后分配它,我避免了同一 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
>>> frame.mask(frame.isna(), lambda x: [{} for _ in range(len(frame)])
Q R
X {2: 2010} {1: 2013}
Y {2: 2011, 3: 2009} {}