【问题标题】:How do I select the group with the least number of null values in a groupby?如何选择 groupby 中空值最少的组?
【发布时间】:2018-08-29 17:13:02
【问题描述】:

例子:

row_number |id |firstname | middlename | lastname |
0          | 1 | John     | NULL       | Doe      |
1          | 1 | John     | Jacob      | Doe      |
2          | 2 | Alison   | Marie      | Smith    |
3          | 2 | NULL     | Marie      | Smith    |
4          | 2 | Alison   | Marie      | Smith    |

我试图弄清楚如何 groupby id,然后为每个 groupby 抓取具有最少 NULL 值数量的行,删除包含最少 NULL 数量的任何额外行都可以(例如,删除 row_number 4,因为它将 row_number 2 与 id=2 的 NULLS 的最少数量联系在一起)

这个例子的答案是 row_numbers 1 和 2

最好是 ANSI SQL,但如果你能想到一种方法,我可以翻译其他语言(例如 python 和 pandas)

编辑: 为平局的情况增加了一行。

【问题讨论】:

  • 为什么会是“1 和 2”?为什么不是其他行?结果不应该将“1和2”汇总为一行吗?
  • 第 1 行和第 2 行的组 (id) 的 NULL 值最少
  • 所以如果我们按 id 分组,那么我们就有包含 id=1 和 id=2 的组。我需要计算这些组中 NULL 的数量,并选择 NULL 数量最少的行
  • 我认为他的意思是row_number 列中的值是 1 或 2,这将是实际的第 2 行和第 3 行...
  • 为什么要标记 pandas ....

标签: python sql database pandas ansi


【解决方案1】:

哦,您想要null 值最少的行。我建议:

select t.*
from (select t.*,
             dense_rank() over (order by (case when firstname is null then 1 else 0 end) + 
                                         (case when middlename is null then 1 else 0 end) + 
                                         (case when lastname is null then 1 else 0 end)
                               ) as seqnum

      from t
     ) t
where seqnum = 1;

这是 ANSI 标准的 SQL。

【讨论】:

  • 排名必须是per id
  • 这很好用,但正如 Vamsi 所说,我需要能够在 groupby 中使用它
【解决方案2】:

如果你想做这个pandas,你可以这样做:

df[df.assign(NC = df.isnull().sum(1)).groupby('id')['NC'].transform(lambda x: x == x.min())]

输出:

   row_number  id firstname middlename lastname
1           1   1      John      Jacob      Doe
2           2   2    Alison      Marie    Smith

对于决胜局:

添加一行:

df.loc[4,['row_number','id','firstname','middlename','lastname']] = ['4',2,'Mary','Maxine','Maxwell']

然后使用groupbytransformidxmin

df[df.index == df.assign(NC = df.isnull().sum(1)).groupby('id')['NC'].transform('idxmin')]

输出:

  row_number id firstname middlename lastname
1          1  1      John      Jacob      Doe
2          2  2    Alison      Marie    Smith

【讨论】:

  • 这非常有效。我没有提到的是当两行包含相同数量的 NULL 时的决胜局。你会怎么丢掉其中一个?
  • @MylesHollowed 查看更新,您可以使用 idxmin 找到第一次出现最小值的索引。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-01
  • 2022-10-16
  • 2013-02-19
相关资源
最近更新 更多