首页 > 解决方案 > 如何将数据从一个数据帧映射到另一个数据帧的列?

问题描述

我有两个单独的数据框代表不同类型的基于时间的数据。一个包含分布在几个月内的数十万个时间戳。此数据框具有代表一年中的月份、一天中的时间和测量温度的列。第二个数据框包含每个月/小时组合的替换温度。数据大致如下:

df1

时间戳 小时 温度
2021 年 1 月 1 日 00:00:00 1 0 10
2021 年 1 月 1 日 00:00:05 1 0 11
2021 年 1 月 1 日 00:00:07 1 0 8
2021 年 1 月 1 日 00:00:15 1 0 12
2021 年 1 月 1 日 00:01:00 1 1 13

等等

df2

小时 二月 三月 四月 ETC
0 9 12 10 12 ETC
1 10 11 14 15 ETC
2 8 7 12 16 ETC

df2 包含一天中每个小时的行,以及一年中每个月的列(在真实数据集中,月份是数字,我写了名称以使描述清晰)。

我需要将 df2 中包含的月份/小时的数据映射到 df 1 中的温度列。所以 df1 在编辑后应该如下所示。

新df1

时间戳 小时 温度
2021 年 1 月 1 日 00:00:00 1 0 9
2021 年 1 月 1 日 00:00:05 1 0 9
2021 年 1 月 1 日 00:00:07 1 0 9
2021 年 1 月 1 日 00:00:15 1 0 9
2021 年 1 月 1 日 00:01:00 1 1 10

我使用嵌套的 for 循环使其工作,如下所示:

for month in df2.columns:
    for hour in df2.index:
        dT = df2.loc[hour, month]
        df1.loc[(df1['Month'] == month) & (df1['Hour'] == hour), 'Temperature'] = dT

嵌套的 for 循环遍历 df2 中的所有月份和时间,找到 df1 中具有匹配月份和时间的单元格,然后将温度设置为等于从 df2 中读取的温度。

但是这段代码既难以阅读,又执行起来超级慢。有人知道更好的方法吗?

谢谢!

标签: pythonpandasdataframe

解决方案


让我们按顺序调用您的两个数据帧 df1 和 df2 。

首先,确保 Timestamp 是 datetime 并提取月份短名称(我们也可以将月份编号映射到短名称)

df1['Timestamp'] = pd.to_datetime(df1['Timestamp'])
df1['Month_name'] = df1['Timestamp'].dt.month_name().str[:3]

注意。如果速度很关键,则跳过上述步骤并修改您的 df2 以使用月份数字代替月份名称作为列,然后在最后一步中使用 df1 的“月份”列执行合并

然后重做 df2 以取消堆叠月份(这可以直接在下一步中应用或保存在变量中):

df2.set_index('Hour').unstack().rename('Temperature')

最后merge是两个:

df1.merge(df2.set_index('Hour').unstack().rename('Temperature'),
          left_on=['Month_name', 'Hour'],
          right_index=True,
          suffixes=('_old', ''),
         )

输出:

            Timestamp  Month  Hour  Temperature_old Month_name  Temperature
0 2021-01-01 00:00:00      1     0               10        Jan            9
1 2021-01-01 00:00:05      1     0               11        Jan            9
2 2021-01-01 00:00:07      1     0                8        Jan            9
3 2021-01-01 00:00:15      1     0               12        Jan            9
4 2021-01-01 00:01:00      1     1               13        Jan           10

如果您只想保留新温度,请添加.drop(['Month', 'Temperature_old'], axis=1)


推荐阅读