问题 将计算列附加到现有数据框


我开始学习熊猫了,我正在关注这个问题 这里 并且无法让解决方案为我工作,我得到一个索引错误。这就是我所拥有的

from pandas import *
import pandas as pd
d = {'L1' : Series(['X','X','Z','X','Z','Y','Z','Y','Y',]),
     'L2' : Series([1,2,1,3,2,1,3,2,3]),
     'L3' : Series([50,100,15,200,10,1,20,10,100])}
df = DataFrame(d)  
df.groupby('L1', as_index=False).apply(lambda x : pd.expanding_sum(x.sort('L3', ascending=False)['L3'])/x['L3'].sum())

输出以下内容(我正在使用iPython)

L1   
X   3    0.571429
    1    0.857143
    0    1.000000
Y   8    0.900901
    7    0.990991
    5    1.000000
Z   6    0.444444
    2    0.777778
    4    1.000000
dtype: float64

然后,我尝试在帖子中建议的标签“new”下附加累积数字计算

df["new"] = df.groupby("L1", as_index=False).apply(lambda x : pd.expanding_sum(x.sort("L3", ascending=False)["L3"])/x["L3"].sum())

我明白了:

   2196                         value = value.reindex(self.index).values
   2197                     except:
-> 2198                         raise TypeError('incompatible index of inserted column '
   2199                                         'with frame index')
   2200 
TypeError: incompatible index of inserted column with frame index

有谁知道问题是什么?如何将计算的值重新插入到数据框中,以便按顺序显示值(对于每个标签X,Y,Z,以“new”降序)


5088
2017-12-23 06:03


起源

@joris既然你回答了类似的问题,你有什么见解吗?
什么版本的 pandas 你正在用吗?以上似乎对我有用。 - DSM
@DSM我使用的是pandas == 0.12.0


答案:


问题是,正如错误消息所示,您要插入的计算列的索引与索引不兼容 df

指数 df 是一个简单的索引:

In [8]: df.index
Out[8]: Int64Index([0, 1, 2, 3, 4, 5, 6, 7, 8], dtype='int64')

虽然计算列的索引是MultiIndex(你也可以在输出中看到),假设我们称之为 new_column

In [15]: new_column.index
Out[15]: 
MultiIndex
[(u'X', 3), (u'X', 1), (u'X', 0), (u'Y', 8), (u'Y', 7), (u'Y', 5), (u'Z', 6), (u'Z', 2), (u'Z', 4)]

因此,您无法将其插入框架中。然而, 这是0.12中的错误,因为它确实在0.13(测试链接问题中的答案)和关键字 as_index=False 应该确保专栏 L1 未添加到索引中。

解决方案为0.12
删除MultiIndex的第一级,以便返回原始索引:

In [13]: new_column = df.groupby('L1', as_index=False).apply(lambda x : pd.expanding_sum(x.sort('L3', ascending=False)['L3'])/x['L3'].sum())
In [14]: df["new"] = new_column.reset_index(level=0, drop=True)

在pandas 0.13(开发中)这是固定的(https://github.com/pydata/pandas/pull/4670)。正是由于这个原因 as_index=False 用于groupby调用,所以列 L1 (您分组的目标)未添加到索引(创建MultiIndex),因此保留原始索引并将结果附加到原始帧。但似乎是 as_index 使用时,关键字在0.12中被忽略 apply


15
2017-12-23 09:53



旁白:我想 df = df.sort(["L1", "L3"], ascending=[True, False]); df["new"] = df.groupby("L1")["L3"].transform(lambda x: x.cumsum()/x.sum()) 看起来有点清洁。 - DSM
@DSM啊,是的,确实这也有效。但随着 apply 它没有。你知道这两种情况之间的区别是什么? - joris
@joris很好的答案,工作得很完美。谁知道我在StackOverflow中的第一个问题是关于熊猫的一个错误:-)