2013-10-11 4 views
0

У меня есть такой DataFrame (это его мультииндексированных DataFrame Я не уверен, если я понимаю, это правильно ...?):панды - выбор более низкого уровня в DataFrame сделать ffill

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 

Я знаю, что могу сделать это итерация variable1 и variable2, для каждого из них делает что-то вроде:

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

Но я предполагаю, что должен быть способ, чтобы избежать это ...

ответ

1

Немного сложно из-за необходимости назначать результаты.

Сначала поменяйте уровни, положив переменную 3 вверху; Затем ffill легко вычисляется и назначается обратно.

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

Великим. В производственной ситуации я борюсь с 'AttributeError: _ref_locs', но я думаю, что это не связано ... –

+0

было несколько ошибок в 0.12, которые вызывают это (это связано с дубликатами в столбцах). – Jeff

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()

Смежные вопросы