【问题标题】:Pandas More Efficient way to filter groups that contain a null field?Pandas 过滤包含空字段的组的更有效方法?
【发布时间】:2017-06-03 01:29:37
【问题描述】:

我目前正在尝试过滤掉熊猫中包含空字段的组。我通过迭代所有组来做到这一点。

for _, g in df.groupby(['name', 'group']):
     if not (g['val'].isnull()).any()
         #Do more stuff with group, as none of its records are null

然而,这非常低效,并且已成为我的代码的核心瓶颈。有什么方法可以表示这种行为而不需要遍历每个组,这个数据框非常大。

编辑:

这种行为不会通过简单地删除 groupby 之前的空记录来实现。 groupby 用于区分什么是可接受的组。如果您事先删除所有空记录,则所有组都将通过,这是不希望的。

基本上我正在尝试解决这个问题,对于每个组,确保它不包含空记录,如果它确实丢弃整个组,而不仅仅是记录本身

编辑 2:

这里有一个更具体的例子,假设它的大小并不需要关注性能。

import pandas
import numpy

df = pandas.DataFrame([{'name': 'alpha', 'group': 1, 'val': 100}, {'name': 'alpha', 'group': 1, 'val': numpy.nan},
                      {'name': 'alpha', 'group': 1, 'val': 50}, {'name': 'beta', 'group': 1, 'val': 20}, {'name': 'beta', 'group': 1, 'val': 40},
                      {'name': 'beta', 'group': 2, 'val': numpy.nan}, {'name': 'beta', 'group': 2, 'val': 120}])
print df

   group   name    val
0      1  alpha  100.0
1      1  alpha    NaN
2      1  alpha   50.0
3      1   beta   20.0
4      1   beta   40.0
5      2   beta    NaN
6      2   beta  120.0

for _, g in df.groupby(['name', 'group']):
    if not (g['val'].isnull()).any():
        print g

   group  name   val
3      1  beta  20.0
4      1  beta  40.0

【问题讨论】:

  • 我认为这归结为您试图在if 声明中完成的内容。没有groupbyif 可能会更有效地重写它。
  • 还可以将if not (g['val'].isnull()).any() 重写为if (g['val'].notnull()).all() 以更清晰(尽管我想这是一个偏好问题:))
  • @RobinNemeth 我认为与 piRSquared 的对话暗示了一种从 groupby 语句中删除工作的解决方案。
  • 你对通过过滤器的组做了什么?添加一个列作为该组是否可接受的指示符并仅在可接受的行上应用矢量化操作可能是值得的
  • @RobinNemeth 过滤器之后的操作将很难正确矢量化。但是,此过滤器应将集合过滤到其原始大小的 0.5% 左右。所以这些操作对整体性能影响不大。

标签: python pandas


【解决方案1】:

filter within the groupby 上下文采用callable,它返回一个bool,用于确定是否包含该组。我会这样做:

# Truth values across whole grouped dataframe on what pandas thinks is null
#                                                \ ______
#                                                /        \
df.groupby(['name', 'group']).filter(lambda df: df.notnull().values.all())
#                                                             \________/
#                                                             /
# Letting numpy determine if everything in the 2-D array is True

【讨论】:

  • 这会带来明显的加速吗?过滤器方法仍将迭代每个组并应用逻辑数据帧操作。但是,它更清洁。不知道这样的方法与 groupby 对象相关联。
  • @jab 这是一个公平的问题。提供一些数据,我会告诉你。另外,我不知道你在循环的其余部分在做什么。这些事情可能能够以矢量化方式执行,也可能不能够。您提供的信息很少。
  • 我尝试添加一个示例(一个非常简化的版本),我不会关心循环体的其余部分,因为过滤后的结果只会是原始大小的 0.5% 左右。跨度>
  • 同理,一个组中大约 95% 的时间都存在空值。
  • 也许一个解决方案会涉及获取原始组大小,过滤掉所有 nan 记录,然后最终获得新的组大小(然后比较新旧的大小)会更有效?
【解决方案2】:

您不需要迭代。只需使用 df.isnull()。它将返回一个布尔值的 DataFrame。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-15
    • 2018-10-12
    • 2018-06-05
    • 1970-01-01
    • 2023-01-19
    • 1970-01-01
    • 2014-05-30
    相关资源
    最近更新 更多