Я работаю с DataFrame в Python, используя pandas, и пытаюсь применить несколько условий для фильтрации строк на основе значений температуры из нескольких столбцов. Однако после применения моих условий и использования dropna()
я получаю ноль строк, хотя ожидаю, что некоторые данные будут соответствовать этим условиям.
Цель — сравнить с температурой окружающей среды +40 C, и если значение превышает это значение, заменить его на NaN. В противном случае сохраните исходное значение.
Вот образец моего DataFrame и условий, которые я применяю:
data = {
'Datetime': ['2022-08-04 15:06:00', '2022-08-04 15:07:00', '2022-08-04 15:08:00',
'2022-08-04 15:09:00', '2022-08-04 15:10:00'],
'Temp1': [53.4, 54.3, 53.7, 54.3, 55.4],
'Temp2': [57.8, 57.0, 87.0, 57.2, 57.5],
'Temp3': [59.0, 58.8, 58.7, 59.1, 59.7],
'Temp4': [46.7, 47.1, 80, 46.9, 47.3],
'Temp5': [52.8, 53.1, 53.0, 53.1, 53.4],
'Temp6': [50.1, 69, 50.3, 50.3, 50.6],
'AmbientTemp': [29.0, 28.8, 28.6, 28.7, 28.9]
}
df1 = pd.DataFrame(data)
df1['Datetime'] = pd.to_datetime(df1['Datetime'])
df1.set_index('Datetime', inplace=True)
Код:
temp_cols = ['Temp1', 'Temp2', 'Temp3', 'Temp4', 'Temp5', 'Temp6']
ambient_col = 'AmbientTemp'
condition = (df1[temp_cols].lt(df1[ambient_col] + 40, axis=0))
filtered_df = df1[condition].dropna()
print(filtered_df.shape)
Ответ:
(0, 99)
Проблема:
Несмотря на то, что ожидаются действительные данные, соответствующие условиям, результирующий DataFrame оказывается пустым после применения фильтра и удаления значений NaN. Что может быть причиной этой проблемы и как ее исправить?
Как выглядит condition
?
@Mainland, какова твоя конечная цель? Если вы объедините маску и dropna
, было бы гораздо эффективнее использовать напрямую df[(df1[temp_cols].lt(df1[ambient_col] + 40, axis=0)).all(axis=1)]
, как показано в моем ответе.
Ваше условие — DataFrame, если вы хотите выбрать по строке, вам следует агрегировать с любым / всем:
condition = (df1[temp_cols].lt(df1[ambient_col] + 40, axis=0)).all(axis=1)
Выход:
Temp1 Temp2 Temp3 Temp4 Temp5 Temp6 AmbientTemp
Datetime
2022-08-04 15:06:00 53.4 57.8 59.0 46.7 52.8 50.1 29.0
2022-08-04 15:09:00 54.3 57.2 59.1 46.9 53.1 50.3 28.7
2022-08-04 15:10:00 55.4 57.5 59.7 47.3 53.4 50.6 28.9
Если вы хотите замаскировать значения, используйте где после переиндексации:
df1.where(condition.reindex(columns=df1.columns, fill_value=True))
Выход:
Temp1 Temp2 Temp3 Temp4 Temp5 Temp6 AmbientTemp
Datetime
2022-08-04 15:06:00 53.4 57.8 59.0 46.7 52.8 50.1 29.0
2022-08-04 15:07:00 54.3 57.0 58.8 47.1 53.1 NaN 28.8
2022-08-04 15:08:00 53.7 NaN 58.7 NaN 53.0 50.3 28.6
2022-08-04 15:09:00 54.3 57.2 59.1 46.9 53.1 50.3 28.7
2022-08-04 15:10:00 55.4 57.5 59.7 47.3 53.4 50.6 28.9
Используйте DataFrame.where:
condition = (df1[temp_cols].lt(df1[ambient_col] + 40, axis=0))
df1[temp_cols] = df1[temp_cols].where(condition)
Если нужен новый DataFrame, добавьте DataFrame.reindex:
temp_cols = ['Temp1', 'Temp2', 'Temp3', 'Temp4', 'Temp5', 'Temp6']
ambient_col = 'AmbientTemp'
condition = (df1[temp_cols].lt(df1[ambient_col] + 40, axis=0))
filtered_df = df1.where(condition.reindex(df1.columns, fill_value=True, axis=1))
print(filtered_df)
Temp1 Temp2 Temp3 Temp4 Temp5 Temp6 AmbientTemp
Datetime
2022-08-04 15:06:00 53.4 57.8 59.0 46.7 52.8 50.1 29.0
2022-08-04 15:07:00 54.3 57.0 58.8 47.1 53.1 NaN 28.8
2022-08-04 15:08:00 53.7 NaN 58.7 NaN 53.0 50.3 28.6
2022-08-04 15:09:00 54.3 57.2 59.1 46.9 53.1 50.3 28.7
2022-08-04 15:10:00 55.4 57.5 59.7 47.3 53.4 50.6 28.9
Как это работает:
#mask
print(condition)
Temp1 Temp2 Temp3 Temp4 Temp5 Temp6
Datetime
2022-08-04 15:06:00 True True True True True True
2022-08-04 15:07:00 True True True True True False
2022-08-04 15:08:00 True False True False True True
2022-08-04 15:09:00 True True True True True True
2022-08-04 15:10:00 True True True True True True
#added Trues values in mask for missing columns - here `AmbientTemp`
print (condition.reindex(df1.columns, fill_value=True, axis=1))
Temp1 Temp2 Temp3 Temp4 Temp5 Temp6 AmbientTemp
Datetime
2022-08-04 15:06:00 True True True True True True True
2022-08-04 15:07:00 True True True True True False True
2022-08-04 15:08:00 True False True False True True True
2022-08-04 15:09:00 True True True True True True True
2022-08-04 15:10:00 True True True True True True True
Пожалуйста, жестко закодируйте данные в виде кода, чтобы у вас был минимальный воспроизводимый пример, который можно запустить.