2016-06-21 96 views
3

考虑到与值替换楠如下:大熊猫多指标的行和列:从匹配的行

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 

到目前为止,我可以识别重复行并删除,但我只是坚持用值w替换NaN这里需要:

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

    如果我理解正确的,问题是医院匹配时从县B值复制到县的一个。这可以用groupby/fillna(method='bfill')完成。 bfill方法以最接近的非NaN值回填NaN。

    然后,您可以使用d2.drop_duplicates(subset=['Hospital'], keep='first')在医院匹配时保留第一行。


    例如,

    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

    关闭,但医院行保留的标准是基于哪一方缺乏第一年的数据,并且有第二年的数据(满足这两个标准的那一个是保留的数据)。 –

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

    叠加后自然会丢失数据透视后的缺失值。

    重新分配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

    几乎肯定从'.swaplevel(1,2,1)'部到来。在'.unstack(0)'之后。它意味着你调用这个数据帧,它的索引只有一个级别,这意味着你在错误的数据框上调用了它,或者它与问题中表示的不同。 – piRSquared

    +0

    你是对的;我忘了我已经将reset_index()添加到了我的原始代码中。关于函数定义中的row.loc ['A'];有没有办法避免提到标签本身?重复行可能发生在n个组中的任何一组中。 –

    +0

    目前,我认为我不得不重做逻辑。 'row.loc ['A']'正在利用'loc'处理'MultiIndex'的好处。一个即时的解决方法是传递列名:'def manipulate_row(row,to ='A',from ='B')'或类似的东西。 – piRSquared