我已经在pandas上执行了一个groupby,我想要应用一个需要多个输入的复杂函数,并将我想要在原始数据框中刻录的pandas系列作为输出。这对我来说是一个已知的程序并且运作良好 - 在最后一种情况下这是令人兴奋的(我向其道歉是因为无法完整地发布代码)。基本上我得到TypeError: incompatible index of inserted column with frame index
。但是,如下所示,我不应该得到一个。
group_by
部分:
all_in_data_risk['weights_of_the_sac'] = all_in_data_risk.groupby(['ptf', 'ac'])['sac', 'unweighted_weights_by_sac', 'instrument_id', 'risk_budgets_sac'].apply(lambda x: wrapper_new_risk_budget(x, temp_fund_all_ret, method_compute_cov))
其中函数是:
def wrapper_new_risk_budget:
print(x.index)
...
print(result.index)
return result.loc[:, 'res']
引发了这个错误:
raise TypeError('incompatible index of inserted column '
TypeError: incompatible index of inserted column with frame index
问题是:
print(np.array_equal(result.index, x.index))
产生所有True
。这应该是索引匹配的保证,因此问题不应该只是存在。
现在,我理解我提供的信息至少可以说,但您是否碰巧对问题所处的位置有任何见解?
p.s。:我已经尝试在数据框中转换结果并尝试将输出重新转换为pd.Series(result.loc[:, 'res'].values, index=result.index)
答案 0 :(得分:1)
好的,出于我理解的原因,当我在代码中执行合并时,尽管他们的numpy表示是等效的,但是在pandas'之前它们之间的其他东西是不同的。眼睛。我尝试了合并的解决方法(更长,更低效),现在使用更传统的手段。
今天我没有能够发布完整的例子,因为我时间非常紧迫,我有一个迫在眉睫的截止日期,但我会尽快完成它,以表达对已经回答的人的尊重或试图这样做以及所有其他用户可能会在解决这个问题时找到有益的东西
答案 1 :(得分:0)
我遇到了这个问题并找到了解决方法。 就我而言,我需要这样做:df.groupby('id').apply(func),然后它返回一个 nx1 数据帧,它的形状与 df.shape[0] 完全相同,但它发生了同样的问题。
因为第一次groupby的时候,会收到一个multiple index,和df不同。
但是可以通过重置和重新指定原点索引来解决问题,例如:
df['a']=df.groupby('id').apply(lambda x:func(x)).reset_index().set_index('level_1').drop('id',axis=1 )
顺便说一句,你应该非常小心这个函数。返回数据帧应包含与 df 相同的索引。
答案 2 :(得分:0)
简化问题:
在最初的问题中应该这样做:
df[‘new_column’] = df.groupby(...).aggregationfunction()
如果至少满足以下条件之一,这通常有效:
如果没有同时给出两个条件,可能会出现错误“TypeError:插入列的索引与帧索引不兼容”。
上升错误示例
看下面的例子:
df = pd.DataFrame({'foo':[0,1]*2,'foo2':np.zeros(4).astype(int),'bar':np.arange(4)})
df
> foo foo2 bar
> 0 0 0 0
> 1 1 0 1
> 2 0 0 2
> 3 1 0 3
df['bar_max'] = df.groupby(['foo','foo2'])['bar'].max()
> TypeError: incompatible index of inserted column with frame index
解决方案
在 groupby 中使用“as_index= False”,您可以创建一个数据框,您可以将其加入原始数据框:
df_grouped = df.groupby(['foo','foo2'], as_index= False)['bar'].max().rename(columns={'bar': 'bar_max'})
df = df.merge(df_grouped, on = ['foo','foo2'])
df
> foo foo2 bar bar_max
>0 0 0 0 2
>1 0 0 2 2
>2 1 0 1 3
>3 1 0 3 3