我有一个包含两列的数据集:company和value 它有一个日期时间索引,其中包含重复项(在同一天,不同的公司具有不同的值)。这些值缺少数据,因此我想使用同一公司的前一个数据点转发缺少的数据。
但是,我似乎无法找到一个很好的方法来做到这一点,而不会遇到奇怪的groupby错误,这表明我做错了什么。
玩具数据:
a = pd.DataFrame({'a': [1, 2, None], 'b': [12,None,14]})
a.index = pd.DatetimeIndex(['2010', '2011', '2012'])
a = a.unstack()
a = a.reset_index().set_index('level_1')
a.columns = ['company', 'value']
a.sort_index(inplace=True)
尝试的解决方案(不起作用:ValueError: cannot reindex from a duplicate axis
):
a.groupby('company').ffill()
a.groupby('company')['value'].ffill()
a.groupby('company').fillna(method='ffill')
Hacky解决方案(提供所需的结果,但显然只是一个丑陋的解决方法):
a['value'] = a.reset_index().groupby(
'company').fillna(method='ffill')['value'].values
这可能是一种简单而优雅的方式,这是如何在熊猫中进行的?
答案 0 :(得分:5)
一种方法是使用transform
功能在分组后填充value
列:
import pandas as pd
a['value'] = a.groupby('company')['value'].transform(lambda v: v.ffill())
a
# company value
#level_1
#2010-01-01 a 1.0
#2010-01-01 b 12.0
#2011-01-01 a 2.0
#2011-01-01 b 12.0
#2012-01-01 a 2.0
#2012-01-01 b 14.0
要进行比较,原始数据框如下所示:
# company value
#level_1
#2010-01-01 a 1.0
#2010-01-01 b 12.0
#2011-01-01 a 2.0
#2011-01-01 b NaN
#2012-01-01 a NaN
#2012-01-01 b 14.0
答案 1 :(得分:5)
您可以将'company'
添加到索引中,使其唯一,并通过ffill
执行简单的groupby
:
a = a.set_index('company', append=True)
a = a.groupby(level=1).ffill()
从这里开始,如果需要,您可以使用reset_index
将索引恢复为正确的日期。我建议将'company'
作为索引的一部分(或者只是将其添加到索引中),因此您的索引仍然是唯一的:
a = a.reset_index(level=1)
答案 2 :(得分:2)
我喜欢使用堆叠和取消堆叠。在这种情况下,它要求我使用'company'
附加索引。
a.set_index('company', append=True).unstack().ffill() \
.stack().reset_index('company')
结论 @ Psidom的解决方案在两种情况下都能发挥最佳效果。
玩具数据
更大的玩具
np.random.seed([3,1415])
n = 10000
a = pd.DataFrame(np.random.randn(n, 10),
pd.date_range('2014-01-01', periods=n, freq='H', name='Time'),
pd.Index(list('abcdefghij'), name='company'))
a *= np.random.choice((1, np.nan), (n, 10), p=(.6, .4))
a = a.stack(dropna=False).rename('value').reset_index('company')