如果该国家/地区的任何数据值都是NaN,我想在我的分层索引中删除整个级别(在本例中为国家/地区)。所以我想从这样的事情出发:
M1 M2
country year
Arab World 2010 5.240002 NaN
2009 NaN NaN
Bangladesh 2010 6.206065 3.7
2009 5.708707 NaN
Canada 2010 7.203803 5.8
2009 6.144833 7.0
Sweden 2010 9.123140 6.0
2009 5.213283 6.1
这样的事情:
M1 M2
country year
Canada 2010 7.203803 5.8
2009 6.144833 7.0
Sweden 2010 9.123140 6.0
2009 5.213283 6.1
我已尝试df.dropna()
使用thresh
选项,以及df.fillna(0)
尝试更轻松地删除国家/地区,但这两种方法都是为了让如果M1和M2包含值,则为DataFrame,例如孟加拉国在2010年。
有没有简洁的方法来解决这个问题?
答案 0 :(得分:2)
此代码块底部的三行执行繁重的工作,其余的将数据放入DataFrame(或多或少)。
# get data
data="""
country year M1 M2
Arab_World 2010 5.240002 NaN
Arab_World 2009 NaN NaN
Bangladesh 2010 6.206065 3.7
Bangladesh 2009 5.708707 NaN
Canada 2010 7.203803 5.8
Canada 2009 6.144833 7.0
Sweden 2010 9.123140 6.0
Sweden 2009 5.213283 6.1"""
from StringIO import StringIO # import from io for python 3
df = pd.read_csv(StringIO(data), header=0, index_col=['country', 'year'], sep=r'\s+')
# manipulate rows
to_drop = df.groupby(level='country').apply(lambda x: x.isnull().any().any())
df = df.reset_index(level=0)
keepers = df[(~to_drop[df.country]).tolist()]
产量
In [13]: print(keepers)
country M1 M2
year
2010 Canada 7.203803 5.8
2009 Canada 6.144833 7.0
2010 Sweden 9.123140 6.0
2009 Sweden 5.213283 6.1
答案 1 :(得分:2)
是的,有一种简洁有效的方法可以解决这个问题。您使用df.dropna()
走在正确的轨道上,只需要在申请之前unstack
数据。
>>> print df
M1 M2
Country Year
Arab World 2009 NaN NaN
2010 5.240002 NaN
Bangladesh 2009 5.708707 NaN
2010 6.206065 3.7
Canada 2009 6.144833 7.0
2010 7.203803 5.8
Sweden 2009 5.213283 6.1
2010 9.123140 6.0
转动DataFrame
以制作"年"最里面的列标签
>>> df1 = df.unstack(level=-1)
删除缺少数据的行
>>> df2 = df1.dropna()
撤销拆散
>>> print df2.stack()
M1 M2
Country Year
Canada 2009 6.144833 7.0
2010 7.203803 5.8
Sweden 2009 5.213283 6.1
2010 9.123140 6.0
把所有这些放在一起:
>>> clean = df.unstack(level=-1).dropna().stack()