Pandas 使用另一列作为条件计算平均值
Pandas calculate mean using another column as condition
我有一个这样的数据框:
observation_time temperature
2021-11-24 10:00:00+00:00 7.22
2021-11-24 10:30:00+00:00 7.33
2021-11-24 11:00:00+00:00 7.44
2021-11-24 11:30:00+00:00 7.50
2021-11-24 12:00:00+00:00 7.50
2021-11-24 12:30:00+00:00 7.50
2021-11-24 13:00:00+00:00 7.44
2021-11-24 13:30:00+00:00 7.61
2021-11-24 14:00:00+00:00 7.67
2021-11-24 14:30:00+00:00 7.78
...
2021-11-27 08:30:00+00:00 7.22
2021-11-27 09:00:00+00:00 7.33
2021-11-27 09:30:00+00:00 7.44
2021-11-27 10:00:00+00:00 7.50
时间步长为30分钟,理论上应该涵盖3天,但很可能会遗漏一些数据。 (数据框只是一个例子,我没有放所有的值。)
我想计算每个时间值在 3 天内的平均值,例如在 10:30 我需要这些天的温度值:2021-11-24、2021-11-25、2021-11-26、
但仅当所有 3 个值都存在时,否则为 NaN。
我开始使用 groupby
和 Grouper
:
df[["observation_time", "temperature"]].groupby(pd.Grouper(key="observation_time", freq="30min", offset="0m", label="right")).mean()
或:
df[["observation_time", "temperature"]].groupby(pd.Grouper(key="observation_time", freq="24H", offset="0m", label="right")).mean()
但是,当然,它们不是正确的解决方案。
然后我试图计算每个时间值的行数:
num = df[["observation_time", "temperature"]].groupby(df["observation_time"].dt.time)["temperature"].count().reset_index()
num.rename(columns={"observation_time": "observation_hour", "temperature": "count_temperature"}, inplace=True)
并使用公共列 observation_hour
:
将此数据框合并到原始数据框
df["observation_hour"] = df["observation_time"].dt.time
df = pd.merge(df, num, how="left")
因此要在同一数据帧上显示时间、温度以及同一小时重复的次数。
我可以使用 groupby
对时间进行分组,但我不知道如何在 count_temperature
上使用条件。
我应该添加到这个:
df.groupby("observation_hour")["temperature"].mean()
某处有类似if df["count_temperature"] == 3
的东西,我不知道在哪里。
最终结果应该是这样的(只是一个例子):
observation_hour mean_temperature
00:00:00+00:00 7.22
00:30:00+00:00 7.44
01:00+00:00 NaN
01:30:00+00:00 7.44
...
22:00:00+00:00 7.44
22:30:00+00:00 NaN
23:00:00+00:00 7.44
23:30:00+00:00 NaN
NaN
值,以防因为我们没有 3 个温度值而无法计算平均值。
有什么想法吗?
您可以从日期时间列中提取时间并仅按时间分组。如果那个 time slow 的观测值少于 3 个,则其平均值为 NaN:
t = pd.date_range("2022-01-01", "2022-01-02", freq="30T").time
grp = df.groupby(df["observation_time"].dt.time)
result = (
grp["temperature"].mean() # Calculate the mean temperature for each 30-min period
.mask(grp.size() < 3, np.nan) # If the period has less than 3 observations, make it nan
.reindex(t) # Make sure we have all periods of a day
.reset_index()
)
我有一个这样的数据框:
observation_time temperature
2021-11-24 10:00:00+00:00 7.22
2021-11-24 10:30:00+00:00 7.33
2021-11-24 11:00:00+00:00 7.44
2021-11-24 11:30:00+00:00 7.50
2021-11-24 12:00:00+00:00 7.50
2021-11-24 12:30:00+00:00 7.50
2021-11-24 13:00:00+00:00 7.44
2021-11-24 13:30:00+00:00 7.61
2021-11-24 14:00:00+00:00 7.67
2021-11-24 14:30:00+00:00 7.78
...
2021-11-27 08:30:00+00:00 7.22
2021-11-27 09:00:00+00:00 7.33
2021-11-27 09:30:00+00:00 7.44
2021-11-27 10:00:00+00:00 7.50
时间步长为30分钟,理论上应该涵盖3天,但很可能会遗漏一些数据。 (数据框只是一个例子,我没有放所有的值。)
我想计算每个时间值在 3 天内的平均值,例如在 10:30 我需要这些天的温度值:2021-11-24、2021-11-25、2021-11-26、 但仅当所有 3 个值都存在时,否则为 NaN。
我开始使用 groupby
和 Grouper
:
df[["observation_time", "temperature"]].groupby(pd.Grouper(key="observation_time", freq="30min", offset="0m", label="right")).mean()
或:
df[["observation_time", "temperature"]].groupby(pd.Grouper(key="observation_time", freq="24H", offset="0m", label="right")).mean()
但是,当然,它们不是正确的解决方案。
然后我试图计算每个时间值的行数:
num = df[["observation_time", "temperature"]].groupby(df["observation_time"].dt.time)["temperature"].count().reset_index()
num.rename(columns={"observation_time": "observation_hour", "temperature": "count_temperature"}, inplace=True)
并使用公共列 observation_hour
:
df["observation_hour"] = df["observation_time"].dt.time
df = pd.merge(df, num, how="left")
因此要在同一数据帧上显示时间、温度以及同一小时重复的次数。
我可以使用 groupby
对时间进行分组,但我不知道如何在 count_temperature
上使用条件。
我应该添加到这个:
df.groupby("observation_hour")["temperature"].mean()
某处有类似if df["count_temperature"] == 3
的东西,我不知道在哪里。
最终结果应该是这样的(只是一个例子):
observation_hour mean_temperature
00:00:00+00:00 7.22
00:30:00+00:00 7.44
01:00+00:00 NaN
01:30:00+00:00 7.44
...
22:00:00+00:00 7.44
22:30:00+00:00 NaN
23:00:00+00:00 7.44
23:30:00+00:00 NaN
NaN
值,以防因为我们没有 3 个温度值而无法计算平均值。
有什么想法吗?
您可以从日期时间列中提取时间并仅按时间分组。如果那个 time slow 的观测值少于 3 个,则其平均值为 NaN:
t = pd.date_range("2022-01-01", "2022-01-02", freq="30T").time
grp = df.groupby(df["observation_time"].dt.time)
result = (
grp["temperature"].mean() # Calculate the mean temperature for each 30-min period
.mask(grp.size() < 3, np.nan) # If the period has less than 3 observations, make it nan
.reindex(t) # Make sure we have all periods of a day
.reset_index()
)