2016-06-21 2 views
3

マッチングからの値ではNaNを置き換えますパンダマルチインデックスの行と列:以下の任意の行

import pandas as pd 
import numpy as np 
df=pd.DataFrame({'County':['A','B','A','B','A','B','A','B','A','B'], 
       'Hospital':['a','b','e','f','i','j','m','n','b','r'], 
       'Enrollment':[44,55,95,54,81,54,89,76,1,67], 
       'Year':['2012','2012','2012','2012','2012','2013', 
         '2013','2013','2013','2013']}) 
d2=pd.pivot_table(df,index=['County','Hospital'],columns=['Year'])#.sort_columns 

d2 

     Enrollment 
     Year  2012 2013 
County Hospital   
A  a  44.0 NaN 
     b  NaN  1.0 
     e  95.0 NaN 
     i  81.0 NaN 
     m  NaN  89.0 
B  b  55.0 NaN 
     f  54.0 NaN 
     j  NaN  54.0 
     n  NaN  76.0 
     r  NaN  67.0 

を、このような「B」として病院が複数回存在し、それが前年度のデータがない場合( 'b'の最初の出現)、私は前の年の値を他の行( 'b')に割り当て、最初の年のデータが含まれていない 'b'の行をこのように削除したい:

 Enrollment 
     Year  2012 2013 
County Hospital   
A  a  44.0 NaN 
     b  55.0 1.0 
     e  95.0 NaN 
     i  81.0 NaN 
     m  NaN  89.0 
B  f  54.0 NaN 
     j  NaN  54.0 
     n  NaN  76.0 
     r  NaN  67.0 

これまでのところ、重複行を特定して削除することはできますが、NaNを値wここで必要:

d2=d2.reset_index()  
d2['dup']=d2.duplicated('Hospital',keep=False) 
  • 旗、削除のために、最新年のデータはありませんとの重複病院:

    Hospital=d2.columns.levels[0][1] 
    
    Y1=d2.columns.levels[1][0] 
    
    Y2=d2.columns.levels[1][1] 
    
    d2['Delete']=np.nan 
    
    d2.loc[(pd.isnull(d2.Enrollment[Y2]))&(d2['dup']==True),'Delete']='Yes' 
    
    1. は、インデックスをリセットした後、重複する病院を特定します

      削除する行以外はすべて削除してください。

      d2=d2.loc[d2['Delete']!='Yes'] 
      
  • 答えて

    3

    を再割り当てします。これはgroupby/fillna(method='bfill')で行うことができます。 bfillメソッドは、最も近いNaN以外の値にNaNをバックフィルします。

    その後、d2.drop_duplicates(subset=['Hospital'], keep='first')を使用すると、病院が一致するときに最初の行を維持できます。例えば


    、ほぼ確実 `.swaplevel(1、2、1)`部分から来て

    import pandas as pd 
    
    df = pd.DataFrame({'County': ['A', 'B', 'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B'], 
            'Hospital': ['a', 'b', 'e', 'f', 'i', 'j', 'm', 'n', 'b', 'r'], 
            'Enrollment': [44, 55, 95, 54, 81, 54, 89, 76, 1, 67], 
            'Year': ['2012', '2012', '2012', '2012', '2012', '2013', 
              '2013', '2013', '2013', '2013']}) 
    d2 = pd.pivot_table(df, index=['County', 'Hospital'], columns=['Year']) 
    d2 = d2.groupby(level='Hospital').fillna(method='bfill') 
    d2 = d2.reset_index() 
    d2 = d2.drop_duplicates(subset=['Hospital'], keep='first') 
    

    収率

     County Hospital Enrollment  
    Year      2012 2013 
    0   A  a  44.0 NaN 
    1   A  b  55.0 1.0 
    2   A  e  95.0 NaN 
    3   A  i  81.0 NaN 
    4   A  m  NaN 89.0 
    6   B  f  54.0 NaN 
    7   B  j  NaN 54.0 
    8   B  n  NaN 76.0 
    9   B  r  NaN 67.0 
    
    +0

    閉じるが、病院の行を維持する基準は、最初の年のデータがなく、2年目のデータを保持している基準に基づいている(2つの基準を満たすものが保持する基準)。 –

    1

    d2ABと並べて並べます。

    e = d2.unstack(0).swaplevel(1, 2, 1).sort_index(1).Enrollment 
    print e 
    
    County  A   B  
    Year  2012 2013 2012 2013 
    Hospital       
    a   44.0 NaN NaN NaN 
    b   NaN 1.0 55.0 NaN 
    e   95.0 NaN NaN NaN 
    f   NaN NaN 54.0 NaN 
    i   81.0 NaN NaN NaN 
    j   NaN NaN NaN 54.0 
    m   NaN 89.0 NaN NaN 
    n   NaN NaN NaN 76.0 
    r   NaN NaN NaN 67.0 
    

    Bから値を割り当て、その後B無効にする適用関数を作成します。

    def manipulate_rows(row): 
        if pd.notnull(row.loc['A'].iloc[1]) & pd.isnull(row.loc['A'].iloc[0]): 
         row.A = row.A.combine_first(row.B) 
         row.B = np.nan 
        return row 
    
    d3 = e.apply(manipulate_rows, axis=1).stack(0).swaplevel(0, 1).sort_index() 
    

    スタッキングすると、回転後に欠損値が自然に削除されます。

    は私が正しく理解していれば、問題は病院が一致したとき郡Aに郡Bから値をコピーすることですd2

    d3.columns = d2.columns 
    
    print d3 
    
           Enrollment  
    Year     2012 2013 
    County Hospital     
    A  a    44.0 NaN 
         b    55.0 1.0 
         e    95.0 NaN 
         i    81.0 NaN 
         m    NaN 89.0 
    B  f    54.0 NaN 
         j    NaN 54.0 
         n    NaN 76.0 
         r    NaN 67.0 
    
    +0

    。 '.unstack(0)'の後ろにあります。これは、あなたがこれを呼び出したデータフレームは、間違ったデータフレームで呼び出されたことを意味するインデックス内のレベルが1つだけだったことを意味します。 – piRSquared

    +0

    あなたは正しいです。元のコードにreset_index()を追加したことを忘れてしまった。関数定義のrow.loc ['A']についてラベル自体の参照を避ける方法はありますか?重複行は、n個のグループのいずれかで発生することがあります。 –

    +0

    現時点では、私はロジックを再加工しなければならないと思います。 'row.loc ['A']'は 'loc'が' MultiIndex'をどのように処理するかを利用しています。すぐに回避するには、 'def manipulate_row(row、to = 'A'、from = 'B')'などの列名を渡すことです。 – piRSquared

    関連する問題