我想将一个元组分配给我的数据帧的布尔索引切片,如下所示:
>>> 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,)
此问题适用于分配到数据框中的单个元素: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
EDIT2: 对不起,我误解了EdChum的回答。之前的编辑不是他所说的,assignment_series应该与mydataframe的长度相同,而不是mydataframe.loc [mydataframe [' colname']> 2,' colname'] as我上面做了。请参阅EdChum的答案。
答案 0 :(得分:1)
你必须构建一个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上屏蔽时,它只需要符合条件的行