【问题标题】:Pandas Grouping and Transform Ignoring NaN忽略 NaN 的 Pandas 分组和转换
【发布时间】:2023-04-09 13:52:01
【问题描述】:

我在对数据框中的非 NA 值进行分组和转换时遇到问题。

所以我的数据框是这样的:

Name Value
A 1
A 2
A NaN
B 3
B 7
B 9
B NaN

我想要的最终输出:

Name Value Weight 1 Weight 2
A 1 0.33 0.5
A 2 0.33 0.5
A NaN 0.33 NaN
B 3 0.25 0.33
B 7 0.25 0.33
B 9 0.25 0.33
B NaN 0.25 NaN

我知道这听起来可能微不足道,但我无法让 Weight 2 在 Name 列的不同分组类别中完美运行。

这是我获取列Weight 1的方法:

df['Weight 1'] = df.groupby(['Name']).transform(lambda x: 1/len(x))

到目前为止,我尝试关注 Weight 2,但引发了 DivisionByZero 警告。输出不正确。

df['Weight 2'] = df.groupby(['Name']).transform(lambda x: 1/np.sum(~np.isnan(x)))

感谢任何帮助。

【问题讨论】:

    标签: python pandas dataframe numpy pandas-groupby


    【解决方案1】:

    count 在计数时忽略空值,size 不会:

    grouper = df.groupby('Name')
    (df.assign(Weight1 = 1/grouper.Value.transform('size'), 
              Weight2 = 1/grouper.Value.transform('count'))
       .assign(Weight2 = lambda df: np.where(df.Value.notna(), 
                                            df.Weight2, np.nan))
     
      Name  Value   Weight1   Weight2
    0    A    1.0  0.333333  0.500000
    1    A    2.0  0.333333  0.500000
    2    A    NaN  0.333333       NaN
    3    B    3.0  0.250000  0.333333
    4    B    7.0  0.250000  0.333333
    5    B    9.0  0.250000  0.333333
    6    B    NaN  0.250000       NaN
    

    【讨论】:

    • 权重 1 是正确的。权重 2 不正确,因为它还将 0.33 和 0.5 分配给 Value 值为 NaN 的行
    • 为了完整性(包括weight 1)。很好的答案!
    【解决方案2】:

    您可以使用GroupBy.count 计算每组中的非NaN 值。然后使用pd.Series.mappd.Series.mask

    mapping = (1 / df.groupby('Name')['Value'].count()).squeeze()
    df['Weight 2'] = df['Name'].map(mapping).mask(df['Value'].isna())
    
      Name  Value  Weight 2
    0    A    1.0  0.500000
    1    A    2.0  0.500000
    2    A    NaN       NaN
    3    B    3.0  0.333333
    4    B    7.0  0.333333
    5    B    9.0  0.333333
    6    B    NaN       NaN
    

    【讨论】:

    • 谢谢伙计...但是您的代码更简单(IMO 更重要)
    • 谢谢。完美运行! mapmask 不太明显的功能很好用。
    • @SaurabhGokhale 它们是非常方便的功能。我已经链接到 pandas 文档,其中有很好的示例解释。
    猜你喜欢
    • 2016-10-17
    • 2014-11-26
    • 1970-01-01
    • 2019-06-03
    • 2019-07-24
    • 1970-01-01
    • 2019-02-09
    • 2017-09-26
    • 1970-01-01
    相关资源
    最近更新 更多