【问题标题】:Attach a calculated column to an existing dataframe将计算列附加到现有数据框
【发布时间】:2014-01-11 08:00:44
【问题描述】:

我开始学习 Pandas,我正在关注here 的问题,但无法获得适合我的解决方案,并且出现索引错误。这就是我所拥有的

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

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

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 的“新”降序。)

【问题讨论】:

  • 您使用的是哪个版本的pandas?以上似乎对我有用。
  • @DSM 我正在​​使用 pandas==0.12.0

标签: python pandas


【解决方案1】:

问题是,正如错误消息所说,您要插入的计算列的索引与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(你分组的fow)没有被添加到索引中(创建一个MultiIndex),所以保留了原始索引并且结果可以附加到原始帧。但是在使用apply 时,似乎as_index 关键字在0.12 中被忽略了。

【讨论】:

  • 旁白:我觉得df = df.sort(["L1", "L3"], ascending=[True, False]); df["new"] = df.groupby("L1")["L3"].transform(lambda x: x.cumsum()/x.sum())看起来更干净一些。
  • @DSM 啊,是的,确实这也有效。但是apply 则不然。你知道在这种情况下两者有什么区别吗?
  • @joris 很好的答案,效果很好。谁知道我在 StackOverflow 上的第一个问题是关于 Pandas 中的一个错误 :-)
猜你喜欢
  • 2019-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-25
  • 2019-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多