首页 > 解决方案 > 合并重复索引的值,其中 NaN 然后先保留

问题描述

假设有一个大的 Timeindex-DataFrame ,时间索引a中有一些重复。

其中一些重复的时间索引可能包含 NaN,其中第二个/第三个/...重复项确实具有值。

一个人如何将值“向上推”到NaNs上面(以便它们被填充),然后删除除第一个之外的所有重复项?(这种向后填充应该只发生在相同日期时间的行之间,例如12.06.2019 00:00:05

pandas使用or的适当/有效方法是什么numpy

Time                       A            B          C        D
12.06.2019 00:00:00   1.1412          NaN    1.21412  1.21412  
12.06.2019 00:00:01   1.1464      1.12643    1.21412  1.21412
12.06.2019 00:00:02      NaN      1.12634        NaN  1.21445
12.06.2019 00:00:02   1.1453          NaN    1.21423      NaN
12.06.2019 00:00:03   1.1536      1.12589    1.21445  2. 2452
12.06.2019 00:00:04   1.1612      1.12978    1.21445  4.12451
12.06.2019 00:00:05   1.1275          NaN        NaN      NaN
12.06.2019 00:00:05      NaN      1.12978    1.21445      NaN
12.06.2019 00:00:06   1.1612      1.12978    1.21445  4.12451
a = pd.DataFrame({'A':[1.1412,1.1464,np.nan,1.1453,1.1536,1.1612,1.1275,np.nan,1.1612],  'B':[np.nan, 1.12643,1.12634,np.nan,1.12589,1.12978,np.nan,1.12978,1.12978],   'C':[1.21412,1.21412,np.nan,1.21423,1.21445,1.21445,np.nan,1.21445,1.21445],   'D':[1.21412,1.21412,1.21445,np.nan,2. 2452,4.12451,np.nan, np.nan, 4.12451]}, indexpd.DatetimeIndex=["12.06.2019 00:00:00","12.06.2019 00:00:01","12.06.2019 00:00:02","12.06.2019 00:00:02","12.06.2019 00:00:03","12.06.2019 00:00:04","12.06.2019 00:00:05","12.06.2019 00:00:05","12.06.2019 00:00:06"])

预期结果:

Time                       A            B          C        D
12.06.2019 00:00:00   1.1412          NaN    1.21412  1.21412  
12.06.2019 00:00:01   1.1464      1.12643    1.21412  1.21412
12.06.2019 00:00:02   1.1453      1.12634    1.21423  1.21445 
12.06.2019 00:00:03   1.1536      1.12589    1.21445  2. 2452
12.06.2019 00:00:04   1.1612      1.12978    1.21445  4.12451
12.06.2019 00:00:05   1.1275      1.12978    1.21445      NaN 
12.06.2019 00:00:06   1.1612      1.12978    1.21445  4.12451

标签: pandasnumpyinterpolationnandata-cleaning

解决方案


加载模块和数据:

import pandas as pd
import io

df = pd.read_csv(io.StringIO("""
Time                       A            B          C        D
12.06.2019 00:00:00   1.1412          NaN    1.21412  1.21412  
12.06.2019 00:00:01   1.1464      1.12643    1.21412  1.21412
12.06.2019 00:00:02      NaN      1.12634        NaN  1.21445
12.06.2019 00:00:02   1.1453          NaN    1.21423      NaN
12.06.2019 00:00:03   1.1536      1.12589    1.21445  2.2452
12.06.2019 00:00:04   1.1612      1.12978    1.21445  4.12451
12.06.2019 00:00:05   1.1275          NaN        NaN      NaN
12.06.2019 00:00:05      NaN      1.12978    1.21445      NaN
12.06.2019 00:00:06   1.1612      1.12978    1.21445  4.12451
"""), sep="\s\s+", engine="python")

用零填充缺失值:

ndf = df.fillna(0)

做一个groupby使用sum它有效地用以前的值替换零。 注意:如果两行在同一列下都有值,则此方法不起作用。

ndf.groupby('Time').agg({'A':sum, 'B':sum, 'C': sum, 'D': sum}) 

作为最后一步,零值可以恢复为np.nan.

更新:如果没有 NAN,则取第一个值

首先,在同一日期下创建没有 NAN 的新数据。对于 12.06.2019 00:00:02,我将 A 列下的 NAN 替换为 1.5,将 B 列下的 NAN 替换为 3.0。

df = pd.read_csv(io.StringIO("""
Time                       A            B          C        D
12.06.2019 00:00:00   1.1412          NaN    1.21412  1.21412  
12.06.2019 00:00:01   1.1464      1.12643    1.21412  1.21412
12.06.2019 00:00:02      1.5      1.12634        NaN  1.21445
12.06.2019 00:00:02   1.1453          3.0    1.21423      NaN
12.06.2019 00:00:03   1.1536      1.12589    1.21445  2.2452
12.06.2019 00:00:04   1.1612      1.12978    1.21445  4.12451
12.06.2019 00:00:05   1.1275          NaN        NaN      NaN
12.06.2019 00:00:05      NaN      1.12978    1.21445      NaN
12.06.2019 00:00:06   1.1612      1.12978    1.21445  4.12451
"""), sep="\s\s+", engine="python")

使用以前的解决方案会导致错误,因为它会在任何地方对值求和。

首先,像以前一样,我们用零填充 NAN。

ndf = df.fillna(0)

以下函数(我们将在groupby命令中使用)检查是否有零。如果有,则取 groupby 类别中数据的总和。如果不是,它将采用第一个出现的值。

def calcfunction(x):
    if any(x == 0 for x in x):
        return(sum(x))
    else:
        return(x.iloc[0])

以下输出groupby显示 A 和 B 列中的日期 12.06.2019 00:00:02 仅采用第一个值,而 C 和 D 列的 NAN 被零替换并与其他现有值相加.

ndf.groupby('Time').agg({'A':calcfunction, 'B':calcfunction, 'C': calcfunction, 'D': calcfunction})

推荐阅读