2016-11-06 218 views
3

我想根据特定条件从DataFrame中选择列。我知道它可以用循环完成,但我的df非常大,所以效率至关重要。列选择的条件是只有non-nan条目或只有nans的序列,后跟一个只有non-nan条目的序列。熊猫中的条件列选择

下面是一个例子。请看下面的数据框:

pd.DataFrame([[1, np.nan, 2, np.nan], [2, np.nan, 5, np.nan], [4, 8, np.nan, 1], [3, 2, np.nan, 2], [3, 2, 5, np.nan]]) 

    0 1 2 3 
0 1 NaN 2.0 NaN 
1 2 NaN 5.0 NaN 
2 4 8.0 NaN 1.0 
3 3 2.0 NaN 2.0 
4 3 2.0 5.0 NaN 

从的话,我想只选择列0和1。关于如何做到这一点没有有效循环有什么建议?

回答

2

逻辑

  • 计数每一列中的空值。如果唯一的空值在开头,那么列中空值的数量应该等于第一个有效索引的位置。
  • 获取第一个有效索引
  • 按空计数对索引进行分片并与第一个有效索引进行比较。如果它们相等,那么这就是一个很好的列

cnull = df.isnull().sum() 
fvald = df.apply(pd.Series.first_valid_index) 
cols = df.index[cnull] == fvald 
df.loc[:, cols] 

enter image description here


与速度提升

老答案

主编
def pir1(df): 
    cnull = df.isnull().sum() 
    fvald = df.apply(pd.Series.first_valid_index) 
    cols = df.index[cnull] == fvald 
    return df.loc[:, cols] 

使用快得多回答相同的逻辑

def pir2(df): 
    nulls = np.isnan(df.values) 
    null_count = nulls.sum(0) 
    first_valid = nulls.argmin(0) 
    null_on_top = null_count == first_valid 
    filtered_data = df.values[:, null_on_top] 
    filtered_columns = df.columns.values[null_on_top] 
    return pd.DataFrame(filtered_data, df.index, filtered_columns) 

enter image description here

+0

由于@piRSquared。这个解决方案确实完成了工作,但运行时间比下面发布的解决方案长3倍以上 – splinter

+0

@splinter我并不感到惊讶。我想到尼基尔走的路线,但我选择了简洁。尼基提供了一个很好的答案。尽管使用相同的逻辑,我会更新我的文章,但利用一些技巧加快速度。 – piRSquared

+0

听起来不错@piRSquared – splinter

1

考虑一个DF所示,其具有以各种可能的位置Nans

Image

1.双方Nans

通过用0和有限值与1的更换所有的NaN创建掩模:

mask = np.where(np.isnan(df), 0, 1) 

采取它横跨每个对应的元素差柱。接下来,取其值。这里的逻辑是,每当每列中有三个唯一值时,则丢弃该列(即→-1,1,0),因为在这种情况下会有序列中断。

想法是取总和并创建一个子集,只要总和结果小于2的值。(因为在mod之后,我们得到1,1,0)。所以,对于极端情况,我们得到总和为2,这些列当然是不相交的,必须丢弃。

criteria = pd.DataFrame(mask, columns=df.columns).diff(1).abs().sum().lt(2) 

最后转置DF,并使用该条件,重新转置来获得具有另一个在一个仅Nans部和有限值所需的结果。

df.loc[:, criteria] 

Image

2. Nans存在于顶部:

mask = np.where(np.isnan(df), 0, 1) 
criteria = pd.DataFrame(mask, columns=df.columns).diff(1).ne(-1).any() 
df.loc[:, criteria] 

Image

+0

非常棒@NickiMaveli,它的速度比上面的解决方案快3倍。 – splinter