Замена пустых значений в DataFrame значением столбца - PullRequest
0 голосов
/ 02 ноября 2018

Скажем, у меня есть следующий кадр данных панд:

df = pd.DataFrame([[3, 2, np.nan, 0],
                    [5, 4, 2, np.nan],
                    [7, np.nan, np.nan, 5],
                    [9, 3, np.nan, 4]],
                    columns=list('ABCD'))

, который возвращает это:

   A    B    C    D
0  3  2.0  NaN  0.0
1  5  4.0  2.0  NaN
2  7  NaN  NaN  5.0
3  9  3.0  NaN  4.0

Мне бы хотелось, чтобы при обнаружении np.nan это значение заменялось значением в столбце A. Так что это будет означать, что результат будет следующим:

   A    B    C    D
0  3  2.0  3.0  0.0
1  5  4.0  2.0  5.0
2  7  7.0  7.0  5.0
3  9  3.0  9.0  4.0

Я пробовал несколько вещей, но я не мог заставить что-либо работать. Кто-нибудь может помочь?

Ответы [ 4 ]

0 голосов
/ 02 ноября 2018

В настоящее время fillna не позволяет транслировать серии по столбцам при выравнивании индексов.

pandas.DataFrame.mask

Это работает точно так же, как мы хотели бы fillna. Находит нулевые значения, заполняет их df.A вдоль axis=0

df.mask(df.isna(), df.A, axis=0)

   A    B    C    D
0  3  2.0  3.0  0.0
1  5  4.0  2.0  5.0
2  7  7.0  7.0  5.0
3  9  3.0  9.0  4.0

pandas.DataFrame.fillna с использованием словаря

Однако вы можете передать словарь в fillna, который скажет ему, что делать для каждого столбца.

df.fillna({k: df.A for k in df})

   A    B    C    D
0  3  2.0  3.0  0.0
1  5  4.0  2.0  5.0
2  7  7.0  7.0  5.0
3  9  3.0  9.0  4.0
0 голосов
/ 02 ноября 2018

Здесь необходимо двойное транспонирование:

cols = ['B','C', 'D']
df[cols] = df[cols].T.fillna(df['A']).T
print(df)
   A    B    C    D
0  3  2.0  3.0  0.0
1  5  4.0  2.0  5.0
2  7  7.0  7.0  5.0
3  9  3.0  9.0  4.0

, потому что:

df[cols] = df[cols].fillna(df['A'], axis=1)
print(df)

NotImplementedError: В настоящее время может заполняться только столбцом dict / Series за столбцом

Другое решение с numpy.where и широковещательной колонкой A:

df = pd.DataFrame(np.where(df.isnull(), df['A'].values[:, None], df), 
                  index=df.index, 
                  columns=df.columns)
print (df)
     A    B    C    D
0  3.0  2.0  3.0  0.0
1  5.0  4.0  2.0  5.0
2  7.0  7.0  7.0  5.0
3  9.0  3.0  9.0  4.0

Спасибо @pir за другое решение:

df = pd.DataFrame(np.where(df.isnull(), df[['A']], df), 
                  index=df.index, 
                  columns=df.columns)
0 голосов
/ 02 ноября 2018

DO fillna с reindex

df.fillna(df[['A']].reindex(columns=df.columns).ffill(1))
Out[20]: 
   A    B    C    D
0  3  2.0  3.0  0.0
1  5  4.0  2.0  5.0
2  7  7.0  7.0  5.0
3  9  3.0  9.0  4.0

Или combine_first

df.combine_first(df.fillna(0).add(df.A,0))
Out[35]: 
   A    B    C    D
0  3  2.0  3.0  0.0
1  5  4.0  2.0  5.0
2  7  7.0  7.0  5.0
3  9  3.0  9.0  4.0
0 голосов
/ 02 ноября 2018
# for each column...
for col in df.columns:
    # I select the np.nan and I replace then with the value of A
    df.loc[df[col].isnull(), col] = df["A"]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...