大熊猫多指标的行和列:从匹配的行
考虑到与值替换楠如下:大熊猫多指标的行和列:从匹配的行
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'
-
重置索引后,找出重复的医院
保留除删除行外的所有行:
d2=d2.loc[d2['Delete']!='Yes']
如果我理解正确的,问题是医院匹配时从县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
操纵d2
将A
和B
并排放置。
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
几乎肯定从'.swaplevel(1,2,1)'部到来。在'.unstack(0)'之后。它意味着你调用这个数据帧,它的索引只有一个级别,这意味着你在错误的数据框上调用了它,或者它与问题中表示的不同。 – piRSquared
你是对的;我忘了我已经将reset_index()添加到了我的原始代码中。关于函数定义中的row.loc ['A'];有没有办法避免提到标签本身?重复行可能发生在n个组中的任何一组中。 –
目前,我认为我不得不重做逻辑。 'row.loc ['A']'正在利用'loc'处理'MultiIndex'的好处。一个即时的解决方法是传递列名:'def manipulate_row(row,to ='A',from ='B')'或类似的东西。 – piRSquared
关闭,但医院行保留的标准是基于哪一方缺乏第一年的数据,并且有第二年的数据(满足这两个标准的那一个是保留的数据)。 –