在Pandas中分配给容器

4 投票
2 回答
20264 浏览
提问于 2025-04-18 03:47

我想把Pandas中某一列里的None值替换成一个空列表。

需要注意的是,这一列中有些值可能已经是空列表了,我不想去改动那些。

我试过:

indices = np.equal(df[col],None)
df[col][indices] = []

还有

indices = np.equal(df[col],None)
df[col][indices] = list()

但是这两种方法都失败了,错误信息是:

ValueError: Length of replacements must equal series length

为什么会这样?我该怎么把那些特定的行更新为一个空列表呢?

2 个回答

1

编辑:我保留了我原来的回答,但我没有测试就发上来了,结果对我来说并不管用。

import pandas as pd
import numpy as np
ser1 = pd.Series(['hi',None,np.nan])
ser2 = pd.Series([5,7,9])
df = pd.DataFrame([ser1,ser2]).T

我知道这有点糟糕。而且,显然DataFrame的构造函数(但不是Series的构造函数)会把None转换成np.nan。我也不知道为什么。

df.loc[1,0] = None

所以现在我们有了

    0     1
0   'hi'  5
1   None  7
2   NaN   9

df.columns = ['col1','col2']
mask = np.equal(df['col1'], None)
df.loc[mask, 'col1'] = []

但这并没有赋值。数据框看起来和之前一样。我按照文档推荐的用法来做,赋值基本类型(字符串和数字)是有效的。所以对我来说,问题出在给数据框的条目赋值对象上。我也不知道怎么回事。


(原始回答)

两件事:

  1. 我不太熟悉np.equal,但如果你想捕捉所有空值,pandas.isnull()也应该有效。
  2. 你正在做一种叫“链式赋值”的操作。我不太理解这个问题,但我知道它不管用。在文档中有说明.

试试这个:

mask = pandas.isnull(df[col])
df.loc[mask, col] = list()

或者,如果你只想捕捉None而不想捕捉np.nan

mask = np.equal(df[col].values, None) 
df.loc[mask, col] = list()

注意:虽然pandas.isnull在数据框、系列和数组中都能正常处理None,但numpy.equal在数据框和数组中才会如预期工作。一个全是None的pandas系列不会对其中任何一个返回True。这是因为None只在某些情况下表现得像np.nan。请参见BUG: None不等于None #20442

6

在作业中使用内嵌列表是不被允许的,而且也不推荐这样做。

如果你从头开始创建,是可以做到的。

In [50]: DataFrame({ 'A' : [[],[],1]})
Out[50]: 
    A
0  []
1  []
2   1

[3 rows x 1 columns]

之所以不允许这样做,是因为没有索引(比如在numpy中),你可能会遇到这样的情况:

In [51]: df = DataFrame({ 'A' : [1,2,3] })

In [52]: df.loc[df['A'] == 2] = [ 5 ]

In [53]: df
Out[53]: 
   A
0  1
1  5
2  3

[3 rows x 1 columns]

你可以进行一个赋值操作,其中掩码中为真的值的数量必须和右边的列表/元组/数组的长度相等(也就是你要设置的值)。Pandas允许这样做,也允许长度正好等于左边的长度,或者是一个单一的数值。其他情况都是不被允许的,因为这样会造成歧义(比如你是想对齐还是不对齐?)

举个例子,想象一下:

In [54]: df = DataFrame({ 'A' : [1,2,3] })

In [55]: df.loc[df['A']<3] = [5]
ValueError: cannot set using a list-like indexer with a different length than the value

一个长度为0的列表/元组/数组被认为是错误的,这不是因为做不到,而是通常是用户的错误,没办法明确该怎么做。

总之,不要在pandas对象内部使用列表。这不仅效率低下,还会让理解变得困难甚至不可能。

撰写回答