【问题标题】:Pandas: Filling NA values to be filled based on distribution of existing valuesPandas:根据现有值的分布填充要填充的NA值
【发布时间】:2017-12-05 15:20:25
【问题描述】:

我有一个 pandas 数据框,其中一列 sign up 有多个空值。 sign up 列具有包含多个 OS 的分类值,例如 iOSandroidweb 等。 我想从现有的OS 值中填充NA 值,但应根据OS 值的现有分布填充NA 值。

示例: 可以说,数据集的 OS 值计数分布如下:

signup
android web    14
ios web        16
mac            5
other          3
windows        6
Name: id, dtype: int64

我想根据上述不同 OS 值的分布来填充 NA 值。我想做的原因是保持当前分布,因为填充Mode 值可能会扭曲结果。 有人可以帮助如何实现这一目标。

【问题讨论】:

    标签: python-2.7 python-3.x pandas numpy


    【解决方案1】:

    你可以使用类似 Numpy 的 random.choice

    从适合您描述的框架开始

    import numpy as np
    import pandas as pd
    
    print(df)
        id   signup
    0    1      mac
    1    2      mac
    2    3      mac
    3    4    other
    4    5    other
    5    6  windows
    6    7  windows
    7    8  windows
    8    9  windows
    9   10      NaN
    10  11      NaN
    11  12      NaN
    12  13      NaN
    13  14      NaN
    

    更新在 cmets 中使用 piRSquared 的提示 弄清楚当前的分布

    s = df.signup.value_counts(normalize=True)
    print(s)
    windows    0.444444
    mac        0.333333
    other      0.222222
    Name: signup, dtype: float64
    

    接下来我们将使用布尔索引来过滤我们想要更新的 nan。此外,这是我们通过传递索引(windows、mac 和其他)来使用随机选择的地方,所需的大小和每个注册的分布将用于 probabilities(p) 参数。

    missing = df['signup'].isnull()
    df.loc[missing,'signup'] = np.random.choice(s.index, size=len(df[missing]),p=s.values)
    print(df)
    
        id   signup
    0    1      mac
    1    2      mac
    2    3      mac
    3    4    other
    4    5    other
    5    6  windows
    6    7  windows
    7    8  windows
    8    9  windows
    9   10  windows
    10  11  windows
    11  12  mac
    12  13  windows
    13  14    other
    

    【讨论】:

    • 似乎我们没有以同样的方式理解问题,他的注册栏是具有 NaN 值的栏?
    • 谢谢鲍勃。这很有帮助。
    • df.signup.value_counts(normalize=True)
    • 超级有帮助的@Bob
    【解决方案2】:
    • 查找空值
    • 从非空值中抽取空值的数量。确保设置replace=True
    • 将采样值分配给空位置

    isnull = df.signup.isnull()
    sample = df.signup.dropna().sample(isnull.sum(), replace=True).values
    df.loc[isnull, 'signup'] = sample
    

    【讨论】:

      【解决方案3】:

      首先,我将此作为输入(因为我认为在您的问题中您错误地将我的value 列命名为sign up

              signup  value
      0  android web   14.0
      1      ios web   16.0
      2          mac    5.0
      3        other    3.0
      4      windows    6.0
      5      ios web    NaN
      6          mac    NaN
      7      windows    NaN
      

      知道了,你的问题可以用一行来解决:

      b = df.groupby('signup')['value'].first()[df['signup']]
      

      请不要说b 是 pandas.Series 类型。

      但如果您希望输出是具有相同列名的 DataFrame,请执行以下操作:

      b = pd.DataFrame(df.groupby('signup')['value'].first()[df['signup']],columns=['value']).reset_index()
      b.rename({1:'value'})
      

      如果你print(b),它会输出:

              signup  value
      0  android web   14.0
      1      ios web   16.0
      2          mac    5.0
      3        other    3.0
      4      windows    6.0
      5      ios web   16.0
      6          mac    5.0
      7      windows    6.0
      

      【讨论】:

        猜你喜欢
        • 2022-08-18
        • 1970-01-01
        • 1970-01-01
        • 2020-09-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多