【问题标题】:How can i fill the null values in a datafame with a specific condition in python?如何在 python 中使用特定条件填充数据框中的空值?
【发布时间】:2020-11-06 10:36:34
【问题描述】:

我有以下数据框:

import pandas as pd
import numpy as np

df = pd.DataFrame(np.nan, index=range(1,16), columns=['A','B','C','D','E','F','G','H'])

a = [1550, 41, 9.41, 22.6, 4.74, 3.2, 11.64, 2.23]
b = [1540, 43, 9.41, 22.3, 4.84, 3.12, 11.64, 2.23]
c = [1590, 39, 9.41, 23.7, 4.74, 3.0, 11.64, 2.23]
d = [1540, 41, 9.41, 22.5, 4.74, 3.2, 11.64, 2.23]

df.loc[[1,8,13,15],:] = [a,b,c,d]

看起来像这样:

         A     B     C     D     E     F      G     H
1   1550.0  41.0  9.41  22.6  4.74  3.20  11.64  2.23
2      NaN   NaN   NaN   NaN   NaN   NaN    NaN   NaN
3      NaN   NaN   NaN   NaN   NaN   NaN    NaN   NaN
4      NaN   NaN   NaN   NaN   NaN   NaN    NaN   NaN
5      NaN   NaN   NaN   NaN   NaN   NaN    NaN   NaN
6      NaN   NaN   NaN   NaN   NaN   NaN    NaN   NaN
7      NaN   NaN   NaN   NaN   NaN   NaN    NaN   NaN
8   1540.0  43.0  9.41  22.3  4.84  3.12  11.64  2.23
9      NaN   NaN   NaN   NaN   NaN   NaN    NaN   NaN
10     NaN   NaN   NaN   NaN   NaN   NaN    NaN   NaN
11     NaN   NaN   NaN   NaN   NaN   NaN    NaN   NaN
12     NaN   NaN   NaN   NaN   NaN   NaN    NaN   NaN
13  1590.0  39.0  9.41  23.7  4.74  3.00  11.64  2.23
14     NaN   NaN   NaN   NaN   NaN   NaN    NaN   NaN
15  1540.0  41.0  9.41  22.5  4.74  3.20  11.64  2.23

我希望填充空值: “平均值(null 之前的所有前面的值,null 之后的第一个非 null 后续值)” 注意:如果 null 之后的第一个后续值也为 Null,则代码应查找第一个不为 null 的后续值。

示例: A 列的第 2 行应填写 Average(1550,1540) = 1545

这里“null 之前的所有先前值”= 1550,“null 之后的第一个非 null 后续值”= 1540

同样, A 列的第 3 行应填入 Average(1550,1545,1540) = 1545

这里在null之前的所有值都是1550和1545(1545是我们在上面的步骤中找到的)

null 之后的第一个非 null 后继值又是 1540。

这样下去,A列的第9行应该填满

平均(null 之前的所有值,1590)1590 现在是 null 之后的第一个非 null 后续值。

所以最后我想要的 A 列输出如下所示:

Desired Output Example for A column: 

Row   A
1   1550
2   1545
3   1545
4   1545
5   1545
6   1545
7   1545
8   1540
9   1550
10  1550
11  1550
12  1550
13  1590
14  1549.285
15  1540

同样,我也希望为所有其他列填充我的空值。 由于我是 python 新手,我不知道如何为此编写代码。

非常感谢您对代码的任何帮助。

【问题讨论】:

  • 您能分享您在其中声明数据框的代码吗?
  • @Anton 代码已共享。

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


【解决方案1】:

这是与this 非常相似的帖子,但我认为这已经足够不同了(而且操作也足够复杂),因此需要给出不同的答案。

您可以为每一行定义一个apply 函数:

def foo(row):
    if any(row.isna()):
        next_non_null = df.loc[df.index>row.name, row.isna()].dropna(how='all').index[0]
        df.loc[row.name, row.isna()] = df.expanding().mean().loc[next_non_null, :]

基本逻辑是这样的:

  • 遍历df 并查看每一行。对于每一行:
  • 检查行中是否有缺失值(这样可以节省时间,请参阅上面链接的帖子)
  • 如果有,找到那些缺失值的下一个非空条目的索引:取df,去掉空值,找到大于当前行的行,取第一个索引
  • 用第一个非空值处的dfexpanding 平均值重写当前行的空值

应用这个函数很简单:

df.apply(foo, axis=1)

df 转换为:

             A          B     C          D         E         F      G     H
1   1550.000000  41.000000  9.41  22.600000  4.740000  3.200000  11.64  2.23
2   1545.000000  42.000000  9.41  22.450000  4.790000  3.160000  11.64  2.23
3   1545.000000  42.000000  9.41  22.450000  4.790000  3.160000  11.64  2.23
4   1545.000000  42.000000  9.41  22.450000  4.790000  3.160000  11.64  2.23
5   1545.000000  42.000000  9.41  22.450000  4.790000  3.160000  11.64  2.23
6   1545.000000  42.000000  9.41  22.450000  4.790000  3.160000  11.64  2.23
7   1545.000000  42.000000  9.41  22.450000  4.790000  3.160000  11.64  2.23
8   1540.000000  43.000000  9.41  22.300000  4.840000  3.120000  11.64  2.23
9   1550.000000  41.666667  9.41  22.588889  4.784444  3.142222  11.64  2.23
10  1550.000000  41.666667  9.41  22.588889  4.784444  3.142222  11.64  2.23
11  1550.000000  41.666667  9.41  22.588889  4.784444  3.142222  11.64  2.23
12  1550.000000  41.666667  9.41  22.588889  4.784444  3.142222  11.64  2.23
13  1590.000000  39.000000  9.41  23.700000  4.740000  3.000000  11.64  2.23
14  1549.285714  41.619048  9.41  22.582540  4.781270  3.146349  11.64  2.23
15  1540.000000  41.000000  9.41  22.500000  4.740000  3.200000  11.64  2.23

我不会检查其他列是否正确?

但请注意,这个 apply 正在修改 df,但返回一个空的 DataFrame。 因此,如果您在控制台中工作并运行 apply 行,您将看到一个 None 的 DataFrame 返回。但是如果你之后再次检查df,你应该会看到它已经更新了。

【讨论】:

    【解决方案2】:
    def fill_nulls(ls):
        non_null_index = [i for i in range(len(ls)) if not np.isnan(ls[i])]
        non_null_values = [i for i in ls if not np.isnan(i)]
        if 0 not in non_null_index:
            ls[0] = non_null_values[0]
        for i in range(len(ls)):
            if i == 0:
                pass
            else:
                if np.isnan(ls[i]):
                    left_non_null = [j for j in ls[:i] if not np.isnan(j)]
                    right_non_null = [[j for j in ls[i:] if not np.isnan(j)][0]]
                    fill_value = np.mean(left_non_null + right_non_null)
                    ls[i] = fill_value
                else:
                    pass
                
        return ls
    
    df['A'] = fill_nulls(df['A'].values)
    
    # Output for new df['A'].values
    [1550.0,
     1545.0,
     1545.0,
     1545.0,
     1545.0,
     1545.0,
     1545.0,
     1540.0,
     1550.0,
     1550.0,
     1550.0,
     1550.0,
     1590.0,
     1549.2857142857142,
     1540.0]
    

    【讨论】:

    • 在这种情况下添加你的函数 - if np.isnan(ls[-1]): ls[-1] = non_null_values[-1]
    猜你喜欢
    • 1970-01-01
    • 2020-08-11
    • 2017-11-12
    • 2019-03-17
    • 2019-12-13
    • 2017-12-17
    • 1970-01-01
    • 2018-06-20
    相关资源
    最近更新 更多