У меня есть определенный фрейм данных (df1) с некоторыми значениями переменной с именем «MP10».
df = data = {
"day": [1, 2, 3, 4, 5, 6, 7],
"month": [1, 1, 4, 4, 7, 7, 7],
"year": [2015, 2015, 2016, 2017, 2017, 2019, 2019,],
"mp10": [10, 15, 20, 5, 7, 14, 18]
}
df1 = pd.DataFrame(df)
df1
Но мне нужно изменить значения NaN для определенных дней. И я создал еще один фрейм данных (df2), чтобы найти эти конкретные дни.
df = data = {
"day": [2, 5, 7],
"month": [1, 7, 7],
"year": [2015, 2017, 2019,],
"mp10": [np.NaN, np.NaN, np.NaN]
}
df2 = pd.DataFrame(df)
df2
Я думал, что с помощью pd.merge можно изменить значения, но не получилось.
Как я могу выбрать NaN из df2 и изменить их в df1?
Я подумал, что размещение изображений из моего фрейма данных может помочь. Но я изменю это
@DanielMM дело не в том, что наличие данных бесполезно (бесполезно?), нам просто сложно работать с данными, представленными в виде изображений. Возможность копирования/вставки очень помогает. что ты уже испробовал? Также сложно отлаживать код, которого у нас нет.
Кроме того, данные с ... неоднозначны, лучше создать небольшой, но содержательный пример и предоставить соответствующий ожидаемый результат.
Я создал пример. Возможно, это работает лучше, чем эти изображения.
каков ваш ожидаемый результат?
Я ожидал, что столбец «MP10» будет выглядеть следующим образом: [10, NaN, 20, 5, NaN, 14, NaN]
Спасибо, теперь это гораздо яснее.






Вы можете использовать слияние с indicator=True, чтобы определить индексы, которые нужно удалить:
idx = (df1.reset_index()
.merge(df2, on=['day', 'month', 'year'],
how='left', indicator=True)
.query('_merge == "both"')['index']
)
df1.loc[idx, 'mp10'] = None
Вариант с использованием логического индексирования:
mask = (df1.merge(df2, on=['day', 'month', 'year'],
how='left', indicator=True)
['_merge'].eq('both')
.tolist() # merge doesn't maintain the index
)
df1.loc[mask, 'mp10'] = None
Выход:
day month year mp10
0 1 1 2015 10.0
1 2 1 2015 NaN
2 3 4 2016 20.0
3 4 4 2017 5.0
4 5 7 2017 NaN
5 6 7 2019 14.0
6 7 7 2019 NaN
Или, если вам нужен новый DataFrame:
out = (df1.merge(df2.assign(mp10=1), on=['day', 'month', 'year'],
how='left', suffixes=(None, '_mask'))
.assign(mp10=lambda x: x['mp10'].mask(x.pop('mp10_mask').eq(1)))
)
Большой! Это сработало! Я не знал о «.query», но я прочитаю и узнаю о нем больше.
Я снова просмотрел этот код и заметил, что он работает не идеально. По какой-то причине, когда у df1 было число, оно не изменилось для NaN.
@Дэниел, можешь быть более откровенным?
Я создал еще один ответ и объяснил там. Спасибо за вашу помощь
@DanielMM не используйте ответ, отредактируйте свой вопрос и добавьте следующий пример после существующего. Кроме того, не используйте изображения данных, а предоставьте два входных параметра (df1/df2) в качестве конструкторов DataFrame, как это сделано сейчас для первого примера.
Хорошо, я поменяю. Спасибо!
Я посмотрел на код и понял, что ошибся и допустил ошибку. Прошу прещения за это.
Вы можете просто установить индекс даты и времени самостоятельно и использовать его:
import pandas as pd
import numpy as np
df = pd.DataFrame(
{
"day": [1, 2, 3, 4, 5, 6, 7],
"month": [1, 1, 4, 4, 7, 7, 7],
"year": [2015, 2015, 2016, 2017, 2017, 2019, 2019],
"mp10": [10, 15, 20, 5, 7, 14, 18],
}
)
df = df.assign(datetime=pd.to_datetime(df[["day", "month", "year"]]))
df = df.set_index("datetime")
to_change = pd.to_datetime(
{"day": [2, 5, 7], "month": [1, 7, 7], "year": [2015, 2017, 2019]}
)
df.loc[to_change, "mp10"] = np.nan
>>> df
day month year mp10
datetime
2015-01-01 1 1 2015 10.0
2015-01-02 2 1 2015 NaN
2016-04-03 3 4 2016 20.0
2017-04-04 4 4 2017 5.0
2017-07-05 5 7 2017 NaN
2019-07-06 6 7 2019 14.0
2019-07-07 7 7 2019 NaN
Изображения данных не принимаются, необходимо предоставить минимально воспроизводимый пример и четкое описание логики.