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

ALH*_*ALH 26 python nan pandas

这是我的数据帧:

          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,...
Run Code Online (Sandbox Code Playgroud)

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

 TypeError('Invalid "to_replace" type: \'float\'',)
Run Code Online (Sandbox Code Playgroud)

小智 19

我的方法类似于@ hellpanderrr,但是测试list-ness而不是使用isnan:

df['ids'] = df['ids'].apply(lambda d: d if isinstance(d, list) else [])
Run Code Online (Sandbox Code Playgroud)

我最初尝试使用pd.isnull(或pd.notnull)但是,当给出一个列表时,它返回每个元素的null-ness.

  • 如果您需要在整个数据帧中执行此操作,这对我有用:`df = df.applymap(lambda d: d if isinstance(d, list) else [])` (2认同)

Ale*_*der 16

你可以先使用loc以找出有所有行nanids列,然后通过使用这些行循环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]
Run Code Online (Sandbox Code Playgroud)


Pla*_*ong 13

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

isnull = df.ids.isnull()

df.loc[isnull, 'ids'] = [ [[]] * isnull.sum() ]
Run Code Online (Sandbox Code Playgroud)

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

  • 我非常喜欢这个答案,因为避免了可能成本高昂的“apply”,但我收到错误“使用 ndarray 设置时必须具有相等的 len 键和值”。简单地按照 @Khris 的建议执行 `[[]]` 会给我同样的错误。然而,/sf/answers/4336092211/似乎有效,所以`isna = df[col].isna(); pandas==1.2.2 中的 df.loc[isna, [col]] = pd.Series([[]] * isna.sum()).values` (4认同)
  • 这是最有效的答案。 (2认同)

ron*_*kov 13

一个简单的解决方案是:

df['ids'].fillna("").apply(list)
Run Code Online (Sandbox Code Playgroud)

  • 凉爽的!请注意,这要求 `df['ids']` 仅包含列表,除了缺失值(OP 示例中就是这种情况)。 (3认同)
  • 我已经用你的方法测试了@Nick Edgar 方法。你的速度几乎快两倍。谢谢... (2认同)

tim*_*geb 7

令人惊讶的是,将带有空列表的字典作为值传递似乎适用于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
Run Code Online (Sandbox Code Playgroud)

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

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

注意:对于缺失值很少的大型系列/数据帧,这可能会产生不合理数量的一次性空列表。

pandas1.0.5测试。