熊猫:groupby向前填充日期时间索引

sap*_*ico 3 python datetime group-by missing-data pandas

我有一个包含两列的数据集: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)
Run Code Online (Sandbox Code Playgroud)

尝试过的解决方案(不起作用:) ValueError: cannot reindex from a duplicate axis:

a.groupby('company').ffill() 
a.groupby('company')['value'].ffill() 
a.groupby('company').fillna(method='ffill')
Run Code Online (Sandbox Code Playgroud)

Hacky解决方案(提供所需的结果,但显然只是一个丑陋的解决方法):

a['value'] = a.reset_index().groupby(
    'company').fillna(method='ffill')['value'].values
Run Code Online (Sandbox Code Playgroud)

可能有一种简单而优雅的方式来做到这一点,这是如何在熊猫中进行的?

Psi*_*dom 9

一种方法是使用该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
Run Code Online (Sandbox Code Playgroud)

作为比较,原始数据帧如下所示:

#            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
Run Code Online (Sandbox Code Playgroud)

  • 我发现 ```a['value'] = a.groupby('company')['value'].transform(lambda v: v.ffill())``` 和 `a[ '值'] = a.groupby('公司')['值'].ffill()` (5认同)

roo*_*oot 6

您可以添加'company'到索引中,使其成为独特的,并做了简单的ffill通过groupby:

a = a.set_index('company', append=True)
a = a.groupby(level=1).ffill()
Run Code Online (Sandbox Code Playgroud)

从这里reset_index开始,如有必要,您可以使用将索引恢复为正好日期.我建议保留'company'作为索引的一部分(或者只是将其添加到索引中),因此您的索引仍然是唯一的:

a = a.reset_index(level=1)
Run Code Online (Sandbox Code Playgroud)


piR*_*red 5

我喜欢使用堆叠和拆垛。在这种情况下,它要求我在索引后附加'company'.

a.set_index('company', append=True).unstack().ffill() \
                                   .stack().reset_index('company')
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明


定时

结论@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')
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明