pandas - 合并重复索引的值,其中 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
解决方案
加载模块和数据:
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})
推荐阅读
- java - 当我获得 RecyclerView 时,Android 片段会抛出 NPE
- swift - 在 UITableView 中使用 insertRow 的 Swift 无效更新
- javascript - 如何在输入中更改多个元素的位置
- c# - 如何从序列号列中删除水晶报表中的小数点
- python - 将动态表单中的数据存储在数组字段中(postgrsql)
- php - $t=“ 2022/8/6 15:44:54”;
- javascript - socket.io 和 Nodejs 控制器的问题
- c - 为什么我在数组分配上遇到段错误
- reactjs - 如何将反应组件作为变量传递给子组件?
- java - 按钮不可点击 + 点击时应用程序崩溃