Заполните NaN в пределах 1 столбца df через поиск другого df через pandas

Я видел различные версии этого вопроса, но ни одна из них не соответствует тому, что я пытаюсь сделать: вот мои данные:

Вот df с NaNs:

df = pd.DataFrame({"A": ["10023", "10040", np.nan, "12345", np.nan, np.nan, "10033", np.nan, np.nan],
               "B": [",", "17,-6", "19,-2", "17,-5", "37,-5", ",", "9,-10", "19,-2", "2,-5"],
               "C": ["small", "large", "large", "small", "small", "large", "small", "small", "large"]})

       A      B      C
0  10023      ,  small
1  10040  17,-6  large
2    NaN  19,-2  large
3  12345  17,-5  small
4    NaN  37,-5  small
5    NaN      ,  large
6  10033  9,-10  small
7    NaN  19,-2  small
8    NaN   2,-5  large

Далее у меня есть поиск df с именем df2:

df2 = pd.DataFrame({"B": ['17,-5', '19,-2', '37,-5', '9,-10'],
                "A": ["10040", "54321", "12345", "10033"]})

       B      A
0  17,-5  10040
1  19,-2  54321
2  37,-5  12345
3  9,-10  10033

Я хотел бы заполнить NaNs столбца A на df, просматривая столбец df2.B и возвращая df2.A так, чтобы результирующий dfr выглядел следующим образом:

       A      B      C
0  10023      ,  small
1  10040  17,-6  large
2  54321  19,-2  large
3  10040  17,-5  small
4  12345  37,-5  small
5    NaN      ,  large
6  10033  9,-10  small
7  54321  19,-2  small
8    NaN   2,-5  large

Важные предостережения:

  1. dfs не имеют соответствующих индексов
  2. Содержимое df.A и df2.A не уникально()
  3. Строки df2 составляют уникальные пары.
  4. Предположим, что есть еще не показанные столбцы с NaNs.

Используя pandas, интересующие строки на df будут найдены (я думаю) через: df.loc[df['A'].isnull(),]. Этот ответ казался многообещающим, но я не понимаю, откуда df1 в этом примере. . Мой фактический набор данных намного больше, чем этот, и мне придется заменить несколько столбцов таким образом.


person jmb277    schedule 10.03.2019    source источник


Ответы (2)


Просто используя np.where

df.A=np.where(df.A.isnull(),df.B.map(df2.set_index('B').A),df.A)
df
Out[149]: 
       A      B      C
0  10023      ,  small
1  10040  17,-6  large
2  54321  19,-2  large
3  12345  17,-5  small
4  12345  37,-5  small
5    NaN      ,  large
6  10033  9,-10  small
7  54321  19,-2  small
8    NaN   2,-5  large
person BENY    schedule 10.03.2019

Метод map от Wen-Ben будет быстрее по скорости, но вот еще один способ решить эту проблему, просто для вашего удобства и знаний

Вы можете использовать pd.merge, потому что это в основном проблема join. После слияния мы заполняем и удаляем ненужные столбцы.

df_final = pd.merge(df, df2, on='B', how='left', suffixes=['_1','_2'])
df_final['A'] = df_final.A_1.fillna(df_final.A_2)
df_final.drop(['A_1', 'A_2'], axis=1, inplace=True)

print(df_final)
       B      C      A
0      ,  small  10023
1  17,-6  large  10040
2  19,-2  large  54321
3  17,-5  small  12345
4  37,-5  small  12345
5      ,  large    NaN
6  9,-10  small  10033
7  19,-2  small  54321
8   2,-5  large    NaN
person Erfan    schedule 11.03.2019
comment
спасибо - я тоже работал над версией merge, но я также видел, что map была быстрой. Хорошо выглядишь. - person jmb277; 11.03.2019
comment
Нет проблем, по любым вопросам, пожалуйста, спрашивайте :) - person Erfan; 11.03.2019
comment
кстати @ jmb277, если вы действительно хотите понять merging в деталях. Этот пост идеально подходит для этого: - person Erfan; 11.03.2019