python - 在以重复日期为索引的数据帧上使用 combine_first
问题描述
我有两个数据框,其中包含同一数据框中不同位置的不同日期的气象数据,这是我的数据的更简单版本,它重现了该问题:
df = pd.DataFrame(np.random.randint(0,30,size=(10, 4)), columns=(['Temp', 'Precip', 'Wind', 'Pressure']))
df1 = pd.DataFrame(np.random.randint(0,30,size=(10, 4)), columns=(['Temp', 'Precip', 'Wind', 'Pressure']))
df['Location'] =[2,2,3,3,4,4,5,5,6,6]
df1['Location'] =[2,2,3,3,4,4,5,5,6,6]
这些在 2020 年 5 月 18 日和 19 日为 df 编制索引,5 月 19 日和 20 日为 df1 编制索引,如下所示:
df.index = ["2020-05-18 12:00:00","2020-05-19 12:00:00","2020-05-18 12:00:00","2020-05-19 12:00:00","2020-05-18 12:00:00","2020-05-19 12:00:00","2020-05-18 12:00:00","2020-05-19 12:00:00","2020-05-18 12:00:00","2020-05-19 12:00:00"]
df1.index = ["2020-05-19 12:00:00", "2020-05-20 12:00:00", "2020-05-19 12:00:00", "2020-05-20 12:00:00", "2020-05-19 12:00:00", "2020-05-20 12:00:00", "2020-05-19 12:00:00", "2020-05-20 12:00:00", "2020-05-19 12:00:00", "2020-05-20 12:00:00"]
df.index = pd.to_datetime(df.index)
df1.index = pd.to_datetime(df1.index)
数据框的结构方式意味着每个Location
点在每个数据框中都有 2 天的数据。df 中的第 18 和 19 号,df1 中的第 19 和 20 号。看起来像这样:
我想将这两个数据帧组合到 df3 中,其中我有每个位置点的第 18、19 和 20 个值,其中第 18 个来自 df,第 19 个和第 20 个来自 df1。即 df1 在同一日期覆盖每个位置的 df,然后附加所有后续日期的数据,以生成如下所示的内容:
实际上,我在很多天里有数百个位置,所以这需要根据索引来工作(我认为)。
我试过这样的pd.combine_first
方法:
df.combine_first(df1)
但是(由于索引中的重复日期)这会产生一个数据框,其中的单元格比我想要的多得多——总共应该有 15 个,而且还有更多。
我认为这是由于索引的原因,因为当我尝试一个仅针对一个位置的更简单日期的示例时,它可以正常工作 - 但我无法弄清楚如何在同一数据框中具有多个位置的数据上执行此操作。我真的很感激一些帮助!
编辑:下面标记的答案确实解决了这个问题,但是现在当我想添加与索引长度不匹配的新数据时:
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(0,30,size=(10, 4)), columns=(['Temp', 'Precip', 'Wind', 'Pressure']))
df1 = pd.DataFrame(np.random.randint(0,30,size=(11, 4)), columns=(['Temp', 'Precip', 'Wind', 'Pressure']))
df['Location'] =[2,2,3,3,4,4,5,5,6,6]
df1['Location'] =[1,2,2,3,3,4,4,5,5,6,6]
df.index = ["2020-05-18 12:00:00","2020-05-19 12:00:00","2020-05-18 12:00:00","2020-05-19 12:00:00","2020-05-18 12:00:00","2020-05-19 12:00:00","2020-05-18 12:00:00","2020-05-19 12:00:00","2020-05-18 12:00:00","2020-05-19 12:00:00"]
df1.index = ["2020-05-19 12:00:00", "2020-05-20 12:00:00", "2020-05-19 12:00:00", "2020-05-20 12:00:00", "2020-05-19 12:00:00", "2020-05-20 12:00:00", "2020-05-19 12:00:00", "2020-05-20 12:00:00", "2020-05-19 12:00:00", "2020-05-20 12:00:00", "2020-05-19 12:00:00"]
df.index = pd.to_datetime(df.index)
df1.index = pd.to_datetime(df1.index)
df1
所以我现在有另一个值为 1 的位置,我想将此位置添加到 df,同时使用 df1 的值更新值。当我使用以下代码时:
df = df.set_index(df.groupby(level=0).cumcount(), append=True)
df1 = df1.set_index(df1.groupby(level=0).cumcount(), append=True)
df = df.combine_first(df1).sort_index(level=[1,0]).reset_index(level=1, drop=True)
print (df)
它使用 df2 中的值更新 df,但会删除新位置。有没有办法解决?
解决方案
df3 = pd.concat([df,df1]).reset_index()
df3 = df3.drop_duplicates(subset=["index","Location"], keep="last")
df3 = df3.set_index("index").sort_index().sort_values(by="Location")
In [29]: df3
Out[29]:
Temp Precip Wind Pressure Location
index
2020-05-18 12:00:00 9 13 17 27 2
2020-05-19 12:00:00 23 27 22 0 2
2020-05-20 12:00:00 21 22 0 5 2
2020-05-18 12:00:00 22 27 19 13 3
2020-05-19 12:00:00 4 29 21 0 3
2020-05-20 12:00:00 12 28 11 25 3
2020-05-18 12:00:00 29 8 21 20 4
2020-05-19 12:00:00 10 3 15 25 4
2020-05-20 12:00:00 23 2 14 5 4
2020-05-18 12:00:00 11 19 17 17 5
2020-05-19 12:00:00 13 1 12 7 5
2020-05-20 12:00:00 4 18 25 19 5
2020-05-18 12:00:00 3 21 16 18 6
2020-05-19 12:00:00 16 12 11 12 6
2020-05-20 12:00:00 27 19 13 19 6
In [30]: df3.shape
Out[30]: (15, 5)
推荐阅读
- json - json 路径语法对值进行排序
- c++ - clang-12:错误:安装 Faunus 时链接器命令失败,退出代码为 1
- c++ - 使用 QtWebEngine 退出时 QT 崩溃
- sql - 根据输入值获取次数值
- android - 条纹访问电话号码(谷歌播放警告)
- anylogic - 如何使用 Java 创建 shapetext
- node.js - 如何给APP获取连接权限?
- mongodb - 可以对只有少量文档的集合进行 COLLSCAN 吗?
- timestamp - 获取基板托盘范围内的系统时间
- node.js - Node JS - 如何在节点 JS 中使用 OAuth 1 流实现 GET 请求