【问题标题】:How do I filter an empty DataFrame and still keep the columns of that DataFrame?如何过滤一个空的 DataFrame 并仍然保留该 DataFrame 的列?
【发布时间】:2018-04-21 20:29:02
【问题描述】:

这里有一个例子说明为什么 pandas 是一个非常设计的组合库:

import pandas as pd

df = pd.DataFrame()
df['A'] = [1,2,3]
df['B'] = [4,5,6]
print(df)

df1 = df[df.A.apply(lambda x:x == 4)]
df2 = df1[df1.B.apply(lambda x:x == 1)]
print(df2)

这将打印出来

df
   A  B
0  1  4
1  2  5
2  3  6
df2
Empty DataFrame
Columns: []
Index: []

注意Columns: [] 的方式,这意味着在df2 上的任何进一步/选择都将失败。这是一个大问题,因为这意味着我现在必须始终在尝试从中选择之前检查任何表是否为空,这是一种垃圾行为。

为了清楚起见,明智的、深思熟虑的、合理的、不完全破坏的行为是保留列。

有人愿意提供一些我可以在数据帧 API 的 hack 集合之上应用的 hack 吗?

【问题讨论】:

  • 我希望Columns: [A, B] 在输出中。我知道在这种特殊情况下我可以做df.A == 4,但并不是所有的应用调用都可以这样替换,所以这没有提供答案。

标签: python pandas


【解决方案1】:

Pandas 几乎考虑了我们需要的所有情况,尤其是那些简单的情况

PS:熊猫没有错

df1 = df.loc[df.A.apply(lambda x:x == 4)]
df2 = df1.loc[df1.B.apply(lambda x:x == 1)]
df1
Out[53]: 
Empty DataFrame
Columns: [A, B]
Index: []
df2
Out[54]: 
Empty DataFrame
Columns: [A, B]
Index: []

【讨论】:

  • 这是我想到的答案。使用[] 进行布尔选择会让我们陷入列切片与行切片的歧义(我不想详细说明)。使用.loc 可以明确我们的目标(我们甚至不需要,:)。
【解决方案2】:
df2 = df1[df1.B.apply(lambda x:x == 1).astype(bool)]

所有其他答案都没有抓住重点(除了 Wen's,这是一个不错的选择)

【讨论】:

  • 发生的情况是您正在使用带有空系列的__getitem__(即[])。 Pandas 将其解释为列的一部分。通过使用astype(bool),您正在迫使 Pandas 将其解释为行布尔切片。
猜你喜欢
  • 2016-02-22
  • 2020-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-06
  • 2014-02-06
相关资源
最近更新 更多