繁体   English   中英

熊猫-在DataFrame中选择较低级别进行填充

[英]pandas - selecting a lower level in a DataFrame to do a ffill

我有一个这样的DataFrame(它是一个MultiIndexed DataFrame吗?不确定我是否正确理解了这一点...):

df = pd.DataFrame({'index' : range(8),
'variable1' : ["A","A","B","B","A","B","B","A"],
'variable2' : ["a","b","a","b","a","b","a","b"],
'variable3' : ["x","x","x","y","y","y","x","y"],
'result': [1,0,0,1,1,0,0,1]})

df2 = df.pivot_table(values='result',rows='index',cols=['variable1','variable2','variable3'])

variable1   A               B    
variable2   a       b       a   b
variable3   x   y   x   y   x   y
index                            
0           1 NaN NaN NaN NaN NaN
1         NaN NaN   0 NaN NaN NaN
2         NaN NaN NaN NaN   0 NaN
3         NaN NaN NaN NaN NaN   1
4         NaN   1 NaN NaN NaN NaN
5         NaN NaN NaN NaN NaN   0
6         NaN NaN NaN NaN   0 NaN
7         NaN NaN NaN   1 NaN NaN

现在我想做的是ffill()值,但仅适用于variable3 == 'y' 理想的结果是:

variable1   A               B    
variable2   a       b       a   b
variable3   x   y   x   y   x   y
index                            
0           1 NaN NaN NaN NaN NaN
1         NaN NaN   0 NaN NaN NaN
2         NaN NaN NaN NaN   0 NaN
3         NaN NaN NaN NaN NaN   1
4         NaN   1 NaN NaN NaN   1
5         NaN   1 NaN NaN NaN   0
6         NaN   1 NaN NaN   0   0
7         NaN   1 NaN   1 NaN   0

我知道我可以通过遍历variable1variable2来做到这一点,因为他们每个人都做类似的事情:

df2['A']['a']['y'].ffill()

但我想应该有一种避免这种情况的方法...

由于需要分配结果,因此有些棘手。

首先交换级别,将变量3放在顶部; 然后轻松地计算出填充量并分配回去。

In [44]: x = df2.swaplevel('variable1','variable3',axis=1)

In [45]: x['y'] = x['y'].ffill()

In [46]: x.swaplevel('variable3','variable1',axis=1)
Out[46]: 
variable1   A               B    
variable2   a       b       a   b
variable3   x   y   x   y   x   y
index                            
0           1 NaN NaN NaN NaN NaN
1         NaN NaN   0 NaN NaN NaN
2         NaN NaN NaN NaN   0 NaN
3         NaN NaN NaN NaN NaN   1
4         NaN   1 NaN NaN NaN   1
5         NaN   1 NaN NaN NaN   0
6         NaN   1 NaN NaN   0   0
7         NaN   1 NaN   1 NaN   0

在0.13(即将推出)中,您可以执行此操作

选择所需的子部分,并提供drop_level=False以将其作为完整部分返回(例如,不选择我们选择的水平),然后填充它。

In [77]: df_sub = df2.xs('y',level='variable3',axis=1,drop_level=False).ffill()

In [78]: df_sub
Out[78]: 
variable1   A       B
variable2   a   b   b
variable3   y   y   y
index                
0         NaN NaN NaN
1         NaN NaN NaN
2         NaN NaN NaN
3         NaN NaN   1
4           1 NaN   1
5           1 NaN   0
6           1 NaN   0
7           1   1   0

In [79]: df2.loc[:,df_sub.columns] = df_sub

In [80]: df2
Out[80]: 
variable1   A               B    
variable2   a       b       a   b
variable3   x   y   x   y   x   y
index                            
0           1 NaN NaN NaN NaN NaN
1         NaN NaN   0 NaN NaN NaN
2         NaN NaN NaN NaN   0 NaN
3         NaN NaN NaN NaN NaN   1
4         NaN   1 NaN NaN NaN   1
5         NaN   1 NaN NaN NaN   0
6         NaN   1 NaN NaN   0   0
7         NaN   1 NaN   1 NaN   0

从熊猫0.14.0开始,可能会有更好的方法:

df2.loc[:, (slice(None), slice(None), 'y')] = df2.loc[:, (slice(None), slice(None), 'y')].ffill()

idx = pd.IndexSlice df2.loc[:, (idx[:,:,'y'])] = df2.loc[:, (idx[:,:,'y'])].ffill()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM