2015-07-15 2 views
3

у меня есть данные, что напоминает следующий упрощенный пример:Заполнение NaN в DataFrame на основе значений столбца

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 

... для многих тысяч строк. Мне нужно заполнить на основе значения в 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. Есть идеи?

+0

Оказывается, что Col1 совершенно не имеет значения, верно? Если нет, объясните, почему. – Alexander

ответ

2

Если я правильно понимаю, то вы можете GroupBy на «Col2», а затем вызвать преобразование «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 
+0

Hi Ed. Обратите внимание, что первый B (индекс = 2) должен быть NaN, так как он является первым значением для «B» и не может быть переполнен вперед. – Alexander

+0

@Alexander no ffill происходит здесь, когда наносятся ряды строк. – EdChum

+0

@ Александр OK Я понимаю, что вы имеете в виду – EdChum

0

Вы хотите что-то ищите?

import pandas as pd 
import numpy as np 


df['Col3'] = np.where(df['Col2'] == 'A', df['Col3'].fillna(10.1), df["Col3"]) 

Конечно, замените соответствующим образом.

0

Вы можете взять срезы DataFrame для каждого элемента 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.1 

EDIT: Кажется, метод, представленный @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 
1

Один ответ я нашел следующие:

df['col3'] = df.groupby('Col2').transform('fillna',method='ffill')['col3'] 

Любые мысли?

+0

Я думаю, вы имели в виду 'df.groupby ('Col2'). Transform ('fillna', method = 'ffill') ['Col3']'. В противном случае, похоже, это работает, но только для групп, которые являются последовательными (что либо вопрос, либо нет). –

+0

Согласен, я отредактировал решение, чтобы отразить ваш комментарий. Благодаря! – DrTRD

Смежные вопросы