从另一个DataFrame分配到切片需要匹配列名?

时间:2018-02-03 22:20:41

标签: pandas dataframe slice

如果我想用另一个的值设置(替换)DataFrame的一部分,我应该能够像这样分配一个切片(如此question):

df.loc[rows, cols] = df2

在这种情况下不是这样,它取而代之的是切片:

In [32]: df
Out[32]: 
   A         B
0  1 -0.240180
1  2 -0.012547
2  3 -0.301475

In [33]: df2
Out[33]: 
   C
0  x
1  y
2  z

In [34]: df.loc[:,'B']=df2

In [35]: df
Out[35]: 
   A   B
0  1 NaN
1  2 NaN
2  3 NaN

但它只适用于df2的一个列(系列),如果我想要多列,则不能选择这个列:

In [36]: df.loc[:,'B']=df2['C']

In [37]: df
Out[37]: 
   A  B
0  1  x
1  2  y
2  3  z

如果列名匹配:

In [47]: df3
Out[47]: 
   B
0  w
1  a
2  t

In [48]: df.loc[:,'B']=df3

In [49]: df
Out[49]: 
   A  B
0  1  w
1  2  a
2  3  t

这是预期的吗?我在docs或Stackoverflow中没有看到任何解释。

2 个答案:

答案 0 :(得分:3)

是的,这是预料之中的。标签对齐是大熊猫的核心功能之一。当您使用df.loc[:,'B'] = df2时,需要对齐两个DataFrame:

df.align(df2)
Out: 
(   A         B   C
 0  1 -0.240180 NaN
 1  2 -0.012547 NaN
 2  3 -0.301475 NaN,     A   B  C
 0 NaN NaN  x
 1 NaN NaN  y
 2 NaN NaN  z)

上面显示了每个DataFrame在作为元组对齐时的外观(第一个是df,第二个是df2)。如果您的df2还有一个名为B的列,其值为[1,2,3],那么它将成为:

df.align(df2)
Out: 
(   A         B   C
 0  1 -0.240180 NaN
 1  2 -0.012547 NaN
 2  3 -0.301475 NaN,     A  B  C
 0 NaN  1  x
 1 NaN  2  y
 2 NaN  3  z)

由于B&对齐,您的作业将导致

df.loc[:,'B'] = df2

df
Out: 
   A  B
0  1  1
1  2  2
2  3  3

使用Series时,对齐将位于单个轴上(在示例中为index)。由于它们完全匹配,因此没有任何问题,它会将df2['C']的值分配给df['B']

您可以在对齐之前重命名标签,也可以使用没有标签的数据结构(numpy数组,列表,元组......)。

答案 1 :(得分:1)

您可以使用底层的NumPy数组:

x

Pandas索引始终对行和列的标记都很敏感。在这种情况下,您的行会检出,但您的行不会检出。 (B!= C)。

使用底层的NumPy数组会使操作对索引不敏感。

df.loc[:,'B'] = df2.values df A B 0 1 x 1 2 y 2 3 z 是一个系列时, 工作的原因是因为Series没有列的概念。唯一的对齐是行,它们是对齐的。