在Pandas数据框中,将空列表替换为NaN。

20

我正在尝试将数据中的一些空列表替换为NaN值。但如何在表达式中表示一个空列表?

import numpy as np
import pandas as pd
d = pd.DataFrame({'x' : [[1,2,3], [1,2], ["text"], []], 'y' : [1,2,3,4]})
d

    x           y
0   [1, 2, 3]   1
1   [1, 2]      2
2   [text]      3
3   []          4



d.loc[d['x'] == [],['x']] = d.loc[d['x'] == [],'x'].apply(lambda x: np.nan)
d

ValueError: Arrays were different lengths: 4 vs 0

而且,我想使用d[d['x'] == ["text"]]选择[text],但是会出现ValueError: Arrays were different lengths: 4 vs 1的错误。但是,使用d[d['y'] == 3]选择3是正确的。为什么呢?


1
d.x = d.x.apply(lambda y: np.nan if len(y)==0 else y) 是如何工作的? - Abdou
4个回答

42

如果您希望使用numpy的nan替换列x中的空列表,可以执行以下操作:

d.x = d.x.apply(lambda y: np.nan if len(y)==0 else y)

如果您想将数据框的行子集化为['text'],请尝试以下操作:

d[[y==['text'] for y in d.x]]

我希望这可以帮到你。


4
您可以使用函数 "apply" 来匹配指定的单元格值,无论其是字符串、列表等实例。
例如,在您的情况下:
import pandas as pd
d = pd.DataFrame({'x' : [[1,2,3], [1,2], ["text"], []], 'y' : [1,2,3,4]})
d
    x           y
0   [1, 2, 3]   1
1   [1, 2]      2
2   [text]      3
3   []          4

如果你使用 d == 3 来选择值为 3 的单元格,完全没有问题:

      x       y
0   False   False
1   False   False
2   False   True
3   False   False

然而,如果你使用等号来匹配一个列表,可能会出现异常,例如 d == [text] 或者 d == ['text'] 或者 d == '[text]',如下所示:

有一些解决方案:

  1. 在数据框的指定系列上使用函数 apply(),就像上面的答案中所示:

  1. A more general method with the function applymap() on a Dataframe may be used for the preprocessing step:

    d.applymap(lambda x: x == [])

      x       y
    

    0 False False 1 False False 2 False False 3 True False

希望这能帮助您和其他学习者,如果您在applymap函数中添加类型检查,则会更好,否则可能会导致一些异常情况。

1

回答您的主要问题,只需完全省略空列表即可。如果使用pandas.concat而不是从字典构建数据帧,当一列中有值而另一列没有值时,NaN将自动填充。

>>> import pandas as pd
>>> ser1 = pd.Series([[1,2,3], [1,2], ["text"]], name='x')
>>> ser2 = pd.Series([1,2,3,4], name='y')
>>> result = pd.concat([ser1, ser2], axis=1)
>>> result
           x  y
0  [1, 2, 3]  1
1     [1, 2]  2
2     [text]  3
3        NaN  4

关于您的第二个问题,似乎您无法在元素内搜索。也许您应该将其作为单独的问题提出,因为它与您的主要问题并不是真正相关的。

0

有一种方法可以在不使用apply的情况下完成它(这可能在大型数据框上速度较慢)。

您可以使用列表的.str.len()小技巧:它最初设计用于计算字符串的长度,但也适用于列表。

结合.loc[<condition>, <column>] = np.nan,就能实现: df.loc[df.x.str.len() == 0, "x"] = np.nan

对于您的示例,结果如下:

>>> df = pd.DataFrame({'x' : [[1,2,3], [1,2], ["text"], []], 'y' : [1,2,3,4]})
>>> df
    x   y
0   [1, 2, 3]   1
1   [1, 2]  2
2   [text]  3
3   []  4

>>> df.loc[df.x.str.len() == 0, "x"] = np.nan
>>> df
x   y
0   [1, 2, 3]   1
1   [1, 2]  2
2   [text]  3
3   NaN 4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接