Python 将元组分配给数据帧的多个元素

Python 将元组分配给数据帧的多个元素,python,pandas,indexing,Python,Pandas,Indexing,我想为我的数据帧的布尔索引切片分配一个元组,如下所示: >>> import pandas as pd >>> mydataframe = pd.DataFrame([1,2,3,4,5],columns=['colname']) >>> mydataframe.loc[mydataframe['colname']>2,'colname'] = (1,2) 期望输出: >>> mydataframe colna

我想为我的数据帧的布尔索引切片分配一个元组,如下所示:

>>> import pandas as pd
>>> mydataframe = pd.DataFrame([1,2,3,4,5],columns=['colname'])
>>> mydataframe.loc[mydataframe['colname']>2,'colname'] = (1,2)
期望输出:

>>> mydataframe
   colname
0        1
1        2
2        (1,2,3)
3        (1,2,3)
4        (1,2,3)
但是,pandas没有将元组分配给每个元素,而是尝试将元组的每个元素分配给切片中的一个元素,并且由于形状不匹配而出错

实际产量:

ValueError: shape mismatch: value array of shape (2,) could not be broadcast 
to indexing result of shape (3,)
我尝试使用set_value函数,得到了相同的行为:

>>> mydataframe.set_value(mydataframe['colname']>2,'colname', (1,2))
ValueError: shape mismatch: value array of shape (2,) could not be broadcast
to indexing result of shape (3,)
此问题适用于分配给数据帧中的单个元素:

有没有一种方法可以不用在片中的元素上循环来完成这个赋值

编辑: 根据EdChum的回答,我还尝试了以下操作,但仍然没有达到预期效果:

>>> mydataframe = pd.DataFrame([1,2,3,4,5],columns=['colname'])
>>> assignment_series = pd.Series([(1,2,3)]*np.sum(mydataframe['colname']>2))
    >>>> assignment_series
0    (1, 2, 3)
1    (1, 2, 3)
2    (1, 2, 3)
dtype: object
>>> mydataframe.loc[mydataframe['colname']>2,'colname'] = assignment_series
>>> mydataframe
     colname
0          1
1          2
2  (1, 2, 3)
3        NaN
4        NaN
Edit2:
对不起,我误解了EdChum的回答。前面的编辑不是他所说的,赋值_系列应该和mydataframe长度相同,而不是像我上面所做的那样,mydataframe.loc[mydataframe['colname']>2,'colname']。请参见下面EdChum的答案。

您必须构建一个序列,元组按df的长度重复,以便对齐:

In [37]:
mydataframe = pd.DataFrame([1,2,3,4,5],columns=['colname'])
mydataframe.loc[mydataframe['colname']>2,'colname']=pd.Series([(1,2,3) for x in range(len(mydataframe))])
mydataframe

Out[37]:
     colname
0          1
1          2
2  (1, 2, 3)
3  (1, 2, 3)
4  (1, 2, 3)
因此,这里的关键点是,您希望为每行分配一个元组作为单个元素,因此您需要匹配所需的形状,这是一个5行系列,其索引与lhs匹配,我们使用列表理解将元组重复N行:

[(1,2,3) for x in range(len(mydataframe))]
并将其作为数据参数传递给
系列
,以生成:

In [39]:
pd.Series([(1,2,3) for x in range(len(mydataframe))])

Out[39]:
0    (1, 2, 3)
1    (1, 2, 3)
2    (1, 2, 3)
3    (1, 2, 3)
4    (1, 2, 3)
dtype: object

当您在lhs上进行掩蔽时,它只对满足条件的行进行掩蔽

Thank@EdChum,但它仍然没有达到我的要求。不确定它在这里要做什么,看看我上面的编辑。但是如果你看你生成的序列,你没有做同样的事情。索引从0到2,所以只分配第2行,我生成的序列与非屏蔽序列匹配,所以它对齐正确。哦,抱歉,我误解了你的意思。我没有意识到行索引是在这样的赋值中使用的,我认为它的工作方式更像numpy,并且一个元素一个元素地赋值。现在我想起来,这当然是有道理的。谢谢你的澄清!