Я хотел бы заполнить недостающие значения в одном столбце значениями из другого столбца, используя fillna
метод.
(Я читал, что перебирать каждую строку было бы очень плохой практикой и что было бы лучше делать все за один раз, но я не мог понять, как это сделать fillna
.)
Данные до:
Day Cat1 Cat2
1 cat mouse
2 dog elephant
3 cat giraf
4 NaN ant
Данные после:
Day Cat1 Cat2
1 cat mouse
2 dog elephant
3 cat giraf
4 ant ant
fillna
снимает серию.Ты мог бы сделать
Общая конструкция на RHS использует троичный шаблон из
pandas
поваренной книги (который стоит прочитать в любом случае). Это векторная версияa? b: c
.источник
pd.DataFrame.fillna()
. И я подозреваю, что поведение в крайнем случае может отличаться, например, для несовпадающих длин серий из разных фреймов данных: dfA ['Cat1'], dfB ['Cat2']Просто используйте
value
параметр вместоmethod
:In [20]: df Out[20]: Cat1 Cat2 Day 0 cat mouse 1 1 dog elephant 2 2 cat giraf 3 3 NaN ant 4 In [21]: df.Cat1 = df.Cat1.fillna(value=df.Cat2) In [22]: df Out[22]: Cat1 Cat2 Day 0 cat mouse 1 1 dog elephant 2 2 cat giraf 3 3 ant ant 4
источник
value
- это первый параметр, поэтому joris на самом деле делает то же самое. По его словам, см. Док .method
она указана первой.pandas.DataFrame.combine_first также работает.
( Внимание: поскольку «Столбцы индекса результата будут объединением соответствующих индексов и столбцов», вы должны проверить соответствие индекса и столбцов. )
import numpy as np import pandas as pd df = pd.DataFrame([["1","cat","mouse"], ["2","dog","elephant"], ["3","cat","giraf"], ["4",np.nan,"ant"]],columns=["Day","Cat1","Cat2"]) In: df["Cat1"].combine_first(df["Cat2"]) Out: 0 cat 1 dog 2 cat 3 ant Name: Cat1, dtype: object
Сравните с другими ответами:
%timeit df["Cat1"].combine_first(df["Cat2"]) 181 µs ± 11.3 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each) %timeit df['Cat1'].fillna(df['Cat2']) 253 µs ± 10.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) %timeit np.where(df.Cat1.isnull(), df.Cat2, df.Cat1) 88.1 µs ± 793 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Я не использовал этот метод ниже:
def is_missing(Cat1,Cat2): if np.isnan(Cat1): return Cat2 else: return Cat1 df['Cat1'] = df.apply(lambda x: is_missing(x['Cat1'],x['Cat2']),axis=1)
потому что это вызовет исключение:
TypeError: ("ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''", 'occurred at index 0')
Это означает, что np.isnan может применяться к массивам NumPy с собственным dtype (например, np.float64), но вызывает TypeError при применении к массивам объектов .
Поэтому я пересматриваю метод:
def is_missing(Cat1,Cat2): if pd.isnull(Cat1): return Cat2 else: return Cat1 %timeit df.apply(lambda x: is_missing(x['Cat1'],x['Cat2']),axis=1) 701 µs ± 7.38 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
источник
Вот более общий подход (вероятно, лучше использовать метод fillna)
def is_missing(Cat1,Cat2): if np.isnan(Cat1): return Cat2 else: return Cat1 df['Cat1'] = df.apply(lambda x: is_missing(x['Cat1'],x['Cat2']),axis=1)
источник
Я знаю, что это старый вопрос, но недавно мне понадобилось сделать что-то подобное. Мне удалось использовать следующее:
df = pd.DataFrame([["1","cat","mouse"], ["2","dog","elephant"], ["3","cat","giraf"], ["4",np.nan,"ant"]],columns=["Day","Cat1","Cat2"]) print(df) Day Cat1 Cat2 0 1 cat mouse 1 2 dog elephant 2 3 cat giraf 3 4 NaN ant df1 = df.bfill(axis=1).iloc[:, 1] df1 = df1.to_frame() print(df1)
Что дает:
Cat1 0 cat 1 dog 2 cat 3 ant
Надеюсь, это кому-то поможет!
источник