Заполнение NaN в фрейме данных на основе значений столбца
У меня есть данные, которые напоминают следующий упрощенный пример:
Col1 Col2 Col3
a A 10.1
b A NaN
d B NaN
e B 12.3
f B NaN
g C 14.1
h C NaN
i C NaN
...на многие тысячи рядов. Мне нужно заполнить LNA, основываясь на значении в Col2, используя что-то аналогичное методу ffill. Результат, который я ищу, таков:
Col1 Col2 Col3
a A 10.1
b A 10.1
d B NaN
e B 12.3
f B 12.3
g C 14.1
h C 14.1
i C 14.1
Однако этот метод игнорирует значение в Col2. Есть идеи?
4 ответов:
Если я правильно понял, то вы можете groupby на 'Col2', а затем вызвать transform на 'Col3' и вызвать
ffill:In [35]: df['Col3'] = df.groupby('Col2')['Col3'].transform(lambda x: x.ffill()) df Out[35]: Col1 Col2 Col3 0 a A 10.1 1 b A 10.1 2 d B NaN 3 e B 12.3 4 f B 12.3 5 g C 14.1 6 h C 14.1 7 i C 14.1
Один ответ, который я нашел, следующий:
df['col3'] = df.groupby('Col2').transform('fillna',method='ffill')['col3']Какие-нибудь мысли?
Это то, что вы ищете?
import pandas as pd import numpy as np df['Col3'] = np.where(df['Col2'] == 'A', df['Col3'].fillna(10.1), df["Col3"])Конечно замените соответственно.
Вы можете взять фрагменты фрейма данных для каждого элемента
Col2, а затем объединить результаты.>>> pd.concat((df.loc[df.Col2 == letter, :].ffill() for letter in df.Col2.unique())) Col1 Col2 Col3 0 a A 10.1 1 b A 10.1 2 d B NaN 3 e B 12.3 4 f B 12.3 5 g C 14.1 6 h C 14.1 7 i C 14.1EDIT: похоже, что метод, представленный @EdChum, является самым быстрым на сегодняшний день.
%timeit pd.concat((df.loc[df.Col2 == letter, :].ffill() for letter in df.Col2.unique())) 100 loops, best of 3: 3.57 ms per loop %timeit df.groupby('Col2').transform('fillna',method='ffill')['Col3'] 100 loops, best of 3: 4.59 ms per loop %timeit df.groupby('Col2')['Col3'].transform(lambda x: x.ffill()) 1000 loops, best of 3: 746 µs per loop
Comments