如何用pandas中的空列表[]填充数据帧Nan值?

时间:2015-10-18 14:35:46

标签: python pandas nan

这是我的数据框:

          date                          ids
0     2011-04-23  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...
1     2011-04-24  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...
2     2011-04-25  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...
3     2011-04-26  Nan
4     2011-04-27  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...
5     2011-04-28  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...

我想用[]替换Nan。怎么做? Fillna([])没有用。我甚至试过replace(np.nan, []),但它给出了错误:

 TypeError('Invalid "to_replace" type: \'float\'',)

12 个答案:

答案 0 :(得分:13)

您可以先使用loc找到nan列中ids的所有行,然后使用at循环显示这些行,将其值设置为一个空列表:

for row in df.loc[df.ids.isnull(), 'ids'].index:
    df.at[row, 'ids'] = []

>>> df
        date                                             ids
0 2011-04-23  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
1 2011-04-24  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
2 2011-04-25  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
3 2011-04-26                                              []
4 2011-04-27  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
5 2011-04-28  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

答案 1 :(得分:13)

我的方法类似于@ hellpanderrr' s,而是测试list-ness而不是isnan

df['ids'] = df['ids'].apply(lambda d: d if isinstance(d, list) else [])

我最初尝试使用pd.isnull(或pd.notnull),但在给定列表时,会返回每个元素的空值。

答案 2 :(得分:6)

经过大量的讨论后,我发现这种方法应该是最有效的(没有循环,不适用),只需分配给切片:

isnull = df.ids.isnull()

df.loc[isnull, 'ids'] = [ [[]] * isnull.sum() ]

诀窍是构建正确大小的[]列表(isnull.sum()),然后将其括在一个列表中:您指定的值是包含空列表作为元素的 2D 数组(1列,isnull.sum()行)。

答案 3 :(得分:4)

令人惊讶的是,传递带有空列表作为值的字典似乎对Series.fillna有效,但不适用于DataFrame.fillna-因此,如果要处理单个列,可以使用以下方法:

>>> df
     A    B    C
0  0.0  2.0  NaN
1  NaN  NaN  5.0
2  NaN  7.0  NaN
>>> df['C'].fillna({i: [] for i in df.index})
0    []
1     5
2    []
Name: C, dtype: object

通过将解决方案应用于每列,可以将其扩展到DataFrames。

>>> df.apply(lambda s: s.fillna({i: [] for i in df.index}))
    A   B   C
0   0   2  []
1  []  []   5
2  []   7  []

注意:对于缺少少量缺失值的大型Series / DataFrame,这可能会产生不合理的丢弃空列表。

经过pandas 1.0.5的测试。

答案 4 :(得分:1)

这可能是更快的一种解决方案:

df['ids'].fillna('DELETE').apply(lambda x : [] if x=='DELETE' else x)

答案 5 :(得分:1)

也许不是最短/最优化的解决方案,但我认为它很可读:

# Packages
import ast

# Masking-in nans
mask = df['ids'].isna()

# Filling nans with a list-like string and literally-evaluating such string
df.loc[mask, 'ids'] = df.loc[mask, 'ids'].fillna('[]').apply(ast.literal_eval)

缺点是您需要加载ast程序包。

编辑

我最近发现了内置eval()的存在。这样可以避免导入任何额外的程序包。

# Masking-in nans
mask = df['ids'].isna()

# Filling nans with a list-like string and literally-evaluating such string
df.loc[mask, 'ids'] = df.loc[mask, 'ids'].fillna('[]').apply(eval)

答案 6 :(得分:1)

一个简单的解决方案是:

df['ids'].fillna("").apply(list)

答案 7 :(得分:0)

没有作业:

1)假设我们的数据框中只有浮点数和整数

import math
df.apply(lambda x:x.apply(lambda x:[] if math.isnan(x) else x))

2)对于任何数据帧

import math
def isnan(x):
    if isinstance(x, (int, long, float, complex)) and math.isnan(x):
        return True

df.apply(lambda x:x.apply(lambda x:[] if isnan(x) else x))

答案 8 :(得分:0)

也许更密集:

df['ids'] = [[] if type(x) != list else x for x in df['ids']]

答案 9 :(得分:0)

使用numpy的另一种解决方案:

df.ids = np.where(df.ids.isnull(), pd.Series([[]]*len(df)), df.ids)

或使用Combine_first:

df.ids = df.ids.combine_first(pd.Series([[]]*len(df)))

答案 10 :(得分:-1)

创建一个检查条件的函数,如果没有,则返回一个空列表/空集等。

然后将该函数应用于变量,但如果您愿意,还可以将新计算的变量分配给旧变量或新变量。

aa=pd.DataFrame({'d':[1,1,2,3,3,np.NaN],'r':[3,5,5,5,5,'e']})


def check_condition(x):
    if x>0:
        return x
    else:
        return list()

aa['d]=aa.d.apply(lambda x:check_condition(x))

答案 11 :(得分:-6)

list方法不支持

fillna,但您可以改为使用dict

df.fillna({})