在不删除行的情况下过滤Pandas DataFrame

时间:2013-10-22 00:31:26

标签: python numpy pandas dataframe

我正在尝试在我的Pandas DataFrame上使用where来替换所有不符合NaN标准的单元格。但是,我想以这样的方式执行此操作,始终保留原始DataFrame的形状,而不是从生成的DataFrame中删除任何行。

给出以下DataFrame:

      A    B    C    D
1/1   0    1    0    1
1/2   2    1    1    1
1/3   3    0    1    0 
1/4   1    0    1    2
1/5   1    0    1    1
1/6   2    0    2    1
1/7   3    5    2    3

当列D符合特定条件时,我想在数据框中搜索满足特定条件的所有单元格。在这种情况下,我的标准是:

当列D也是>时,查找大于前一个值的所有单元格。 1

我使用以下语法完成此操作:

matches = df[df > df.shift(1))]
matches = matches[df.D > 1]

我必须将此查询拆分为两个语句,因为df.D是一个系列,并且与整个DataFrame的形状不匹配。根据我之前提到的this question,直到0.14才支持广播&运营商。

我遇到的问题是,在运行第二个语句后,似乎更改了结果数据框的形状,并删除了行。列数保持不变。第一个语句保留原始行数。

为什么第二个语句删除行而第一个语句没有?我怎么能达到相同的结果,但是留下完整的行数呢?

修改

pandas文档说明为了保证形状得到保留,我应该使用where方法而不是布尔索引。但是,似乎不允许执行我的第二个陈述,所以:

matches.where(df.D > 1)

给我以下错误:

  

ValueError:数组条件必须与self

形状相同

2 个答案:

答案 0 :(得分:6)

这比@DSM答案稍微直观一些(但是大熊猫在布尔操作ATM上缺少这种类型的自动广播)

In [58]: df.where((df>df.shift(1)).values & DataFrame(df.D==1).values)
Out[58]: 
      A   B   C   D
1/1 NaN NaN NaN NaN
1/2   2 NaN   1 NaN
1/3 NaN NaN NaN NaN
1/4 NaN NaN NaN NaN
1/5 NaN NaN NaN NaN
1/6   2 NaN   2 NaN
1/7 NaN NaN NaN NaN

请参阅here了解要在0.14中解决的问题

答案 1 :(得分:3)

如果我了解您所追求的内容,您可以通过下拉至numpy级别手动进行广播:

>>> (df > df.shift(1)).values & (df.D == 1)[:,None]
array([[False, False, False, False],
       [ True, False,  True, False],
       [False, False, False, False],
       [False, False, False, False],
       [False, False, False, False],
       [ True, False,  True, False],
       [False, False, False, False]], dtype=bool)

之后您可以使用where

>>> df.where((df > df.shift(1)).values & (df.D == 1)[:,None], np.nan)
      A   B   C   D
1/1 NaN NaN NaN NaN
1/2   2 NaN   1 NaN
1/3 NaN NaN NaN NaN
1/4 NaN NaN NaN NaN
1/5 NaN NaN NaN NaN
1/6   2 NaN   2 NaN
1/7 NaN NaN NaN NaN