我想将一个元组分配给数据框的布尔索引切片,如下所示:
>>> 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)
但是,熊猫没有将元组的每个元素分配给切片,而是尝试将元组的每个元素分配给切片中的元素,并且由于形状不匹配而出错。
实际输出:
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,)
该问题适用于分配给数据框中的单个元素:Add a tuple to a specific cell of a pandas dataframe
有没有一种方法可以执行此分配而无需遍历切片中的元素?
编辑:
我还按照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
编辑2:
抱歉,我误解了EdChum的回答。之前的编辑不是他在说什么,assignment_series的长度应与mydataframe相同,而不是像我上面所做的mydataframe.loc [mydataframe ['colname']> 2,'colname']相同。请参阅下面的EdChum的答案。
最佳答案
您必须构造一个Series
,其中元组重复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))]
并将其作为
Series
产生的数据arg传递: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上屏蔽时,它仅占用满足条件的行