pandas中的条件列选择

时间:2016-11-06 03:16:51

标签: python-3.x pandas dataframe

我想根据特定条件从DataFrame中选择列。我知道它可以通过循环完成,但我的df非常大,因此效率至关重要。列选择的条件是仅具有非纳米条目或仅具有nans的序列,其后仅具有非纳米条目的序列。

这是一个例子。请考虑以下DataFrame:

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 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

如下所示,请考虑DF Nans,其中Nans位于不同的位置:

Image

1。 双方mask = np.where(np.isnan(df), 0, 1) 在场

通过将所有nans替换为0和有限值替换为1来创建掩码:

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

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

想法是获取总和并在总和导致小于2的值的任何地方创建子集。(在采用mod之后,我们得到1,1,0)。因此,对于极端情况,我们得到总和为2,那些列肯定是不相交的,必须丢弃。

DF

最后转置Nans并使用此条件并重新转置以获得所需的结果,其中一部分只有df.loc[:, criteria] 而另一部分只有有限值。

Nans

Image

<强> 2。 mask = np.where(np.isnan(df), 0, 1) criteria = pd.DataFrame(mask, columns=df.columns).diff(1).ne(-1).any() df.loc[:, criteria] 位于顶部:

body{ width:100%; height:100%; }
div1{ width:100%; height:40%; }
div2{ width:100%; height:30%; }
div3{ width:100%; height:30%; }

Image

相关问题