[英]pandas - selecting a lower level in a DataFrame to do a ffill
I have such a DataFrame (is it a MultiIndexed DataFrame? I am not sure if I understand this correctly...): 我有一个这样的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
Now what I want to do is ffill()
the values, but only for variable3 == 'y'
. 现在我想做的是
ffill()
值,但仅适用于variable3 == 'y'
。 The desired result is: 理想的结果是:
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
I know I can do this by iterating over variable1
and variable2
, for each of them doing something like: 我知道我可以通过遍历
variable1
和variable2
来做到这一点,因为他们每个人都做类似的事情:
df2['A']['a']['y'].ffill()
But I guess there should be a method to avoid this... 但我想应该有一种避免这种情况的方法...
A little bit tricky because of the need to assign the results. 由于需要分配结果,因此有些棘手。
First swap the levels, putting variable 3 at the top; 首先交换级别,将变量3放在顶部; ffill is then easily computed and assigned back.
然后轻松地计算出填充量并分配回去。
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
In 0.13 (coming soon), you can do this 在0.13(即将推出)中,您可以执行此操作
Select the sub-section that we want, and provide drop_level=False
to return it as a full section (eg don't the level that we are selection on), and ffill it. 选择所需的子部分,并提供
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
there might be a better way of doing this since pandas 0.14.0: 从熊猫0.14.0开始,可能会有更好的方法:
df2.loc[:, (slice(None), slice(None), 'y')] = df2.loc[:, (slice(None), slice(None), 'y')].ffill()
or idx = pd.IndexSlice df2.loc[:, (idx[:,:,'y'])] = df2.loc[:, (idx[:,:,'y'])].ffill()
或
idx = pd.IndexSlice df2.loc[:, (idx[:,:,'y'])] = df2.loc[:, (idx[:,:,'y'])].ffill()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.