将numpy数组添加到pandas DataFrame单元格依赖于初始化

1 投票
1 回答
71 浏览
提问于 2025-04-14 16:25

我在尝试把一系列的numpy数组作为元素添加到pandas的DataFrame里:

DataFrame的样子

我使用了:

df.loc[df['B']==4,'A'] = [np.array([5, 6, 7, 8]),np.array([2,3])]

这是否可行似乎取决于我如何初始化df:

测试两种不同的df初始化方式

有人能给我解释一下发生了什么吗?

下面是大家可以试试的代码:

不工作的代码

df = pd.DataFrame(columns=['A','B'])
a = [1,2,0,4,5]
b = [3,4,4,7,3]

df['A'] = a
df['B'] = b

df.loc[df['B']==4,'A'] = [np.array([5, 6, 7, 8]),np.array([2,3])]
df

工作的代码

df = pd.DataFrame(columns=['A','B'])
a = [1,2,0,4,5]
b = [3,4,4,7,3]

for i in range(len(a)):
    df.loc[i,'A'] = a[i]
    df.loc[i,'B'] = b[i]

df.loc[df['B']==4,'A'] = [np.array([5, 6, 7, 8]),np.array([2,3])]
df

1 个回答

0

你需要创建一个带有正确索引的 Series

m = df['B']==4

df.loc[m, 'A'] = pd.Series([np.array([5, 6, 7, 8]), np.array([2, 3])],
                           index=df.index[m])

注意,在未来的 pandas 版本中,这可能会引发错误,因为 A 的原始数据类型是整数。你需要先把它转换成对象:

df['A'] = df['A'].astype(object)

m = df['B']==4

df.loc[m, 'A'] = pd.Series([np.array([5, 6, 7, 8]), np.array([2, 3])],
                           index=df.index[m])

输出结果:

              A  B
0             1  3
1  [5, 6, 7, 8]  4
2        [2, 3]  4
3             4  7
4             5  3
为什么第二种方法有效?

不太确定,可能是因为 DataFrame 的内部状态有些特殊(我猜是因为它完全是通过一个循环和一个空的对象 DataFrame 初始化的),但这很可能不是预期的效果,而且非常不稳定。

例如,如果你再添加一列(即使是对象类型),这个方法就会失败:

df = pd.DataFrame(columns=['A','B'])
a = [1,2,0,4,5]
b = [3,4,4,7,3]

df['C'] = 'X'  # we just add one extra column

for i in range(len(a)):
    df.loc[i,'A'] = a[i]
    df.loc[i,'B'] = b[i]

df.loc[df['B']==4,'A'] = [np.array([5, 6, 7, 8]), np.array([2, 3])]
# error

但是从一个单一的块对象 numpy 数组创建 DataFrame 是可行的:

a = [1,2,0,4,5]
b = [3,4,4,7,3]
df = pd.DataFrame(np.c_[a, b].astype('object'), columns=['A','B'])
df.loc[df['B']==4, 'A'] = [np.array([5, 6, 7, 8]), np.array([2, 3])]
# no error

撰写回答