У меня есть исходный фрейм данных df0
с рядом значений, на основе этого кадра данных у меня есть второй фрейм данных, где некоторые исходные значения равны NaN
, df1
.
import pandas as pd
df0 = pd.DataFrame({'col1': [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]})
df1 = pd.DataFrame({'col1': [1,2,None,4,5,6,None,8,None,10,11,None,13,None,None]})
Мне нужно, чтобы df2
было обратным df1
с точки зрения строк с NaN
. Каждая строка, которая является NaN
в df1, должна вернуть свое исходное значение из df0
, а строки, которые не являются NaN
, должны стать NaN
, чтобы я получил следующий фрейм данных:
df2 = pd.DataFrame({'col1': [None,None,3,None,None,None,7,None,9,None,None,12,None,14,15]})
Каков наилучший способ сделать это, если бы это был больший набор данных?
Я имею в виду заменить только столбец col1, в моем фактическом наборе данных есть несколько других столбцов, которые должны оставаться как есть. Извините за путаницу!
Хорошо, ответ был отредактирован. Итак, нужно заменить все столбцы на col1
?
Если вам нужно замаскировать все столбцы, используйте mask + notna ИЛИ где + isna:
df2 = df0.mask(df1['col1'].notna())
# or
df2 = df0.where(df1['col1'].isna())
выход:
col1
0 NaN
1 NaN
2 3.0
3 NaN
4 NaN
5 NaN
6 7.0
7 NaN
8 9.0
9 NaN
10 NaN
11 12.0
12 NaN
13 14.0
14 15.0
Если вам просто нужно заменить col1 и оставить потенциальные другие столбцы нетронутыми, используйте assign и Series.mask:
df2 = df0.assign(col1=df0['col1'].mask(df1['col1'].notna()))
Мне нужен был второй вариант, чтобы другие остались нетронутыми, да, спасибо!
@BasR не был уверен в примере, но рад, что это сработало;)
Используйте Series.where с Series.isna для замены одного столбца другим DataFrame, только в обоих случаях необходим одинаковый индекс:
df0['col1'] = df0['col1'].where(df1['col1'].isna())
print (df0)
col1
0 NaN
1 NaN
2 3.0
3 NaN
4 NaN
5 NaN
6 7.0
7 NaN
8 9.0
9 NaN
10 NaN
11 12.0
12 NaN
13 14.0
14 15.0
Альтернатива с DataFrame.loc и Series.notna:
df0.loc[df1['col1'].notna(), 'col1'] = np.nan
Так что нужно заменить все столбцы, верно?