2017-01-04 6 views
1

Exist dataframe сПрисвоение значения дублировать строку в панд dataframe

Customer Score 
3a62-4799 500 
3a62-4799 NA 
3a62-1234 450 
3a62-1234 NA 

Как найти все дублируют с клиентом и скопировать счет до значения NA.

Я попробовал этот подход

X['Score'][((X.set_index('Customer').index.get_duplicates()) & (X['Score']>0)).any()] =X['Score'] 

Но это не работает

ValueError: Arrays were different lengths:

ответ

5

Я думаю, что вы можете использовать ffill с duplicated, если в каждой группе не только первое никакое значение NaN:

print (df) 
    Customer Score 
0 3a62-4000 NaN 
1 3a62-4799 500.0 
2 3a62-4799 NaN 
3 3a62-1234 450.0 
4 3a62-1234 NaN 

df.loc[df.Customer.duplicated(keep=False), 'Score'] = df.Score.ffill() 
print (df) 
    Customer Score 
0 3a62-4000 NaN 
1 3a62-4799 500.0 
2 3a62-4799 500.0 
3 3a62-1234 450.0 
4 3a62-1234 450.0 

Если несколько значений на группы вы можете заполнить дубликаты на mean (sum, median ...) с transform или apply:

print (df) 
    Customer Score 
0 3a62-4000 NaN 
1 3a62-4799 500.0 
2 3a62-4799 200.0 
3 3a62-4799 NaN 
4 3a62-1234 450.0 
5 3a62-1234 NaN 

df['Score'] = df.groupby('Customer')['Score'].transform(lambda x: x.fillna(x.mean())) 
#df['Score'] = df.groupby('Customer')['Score'].apply(lambda x: x.fillna(x.mean())) 
print (df) 
    Customer Score 
0 3a62-4000 NaN 
1 3a62-4799 500.0 
2 3a62-4799 200.0 
3 3a62-4799 350.0 
4 3a62-1234 450.0 
5 3a62-1234 450.0 
+0

Очень хорошее решение. Благодаря! – Oxymoron88

+0

@ Oxymoron88 - спасибо. – jezrael

+0

Хорошее решение. Плюс один – akrun

0

В качестве альтернативы, вы можете использовать groupby для пересылки заполнения для каждого идентификатора клиента.

df.Score = df.groupby('Customer').ffill() 

Используя набор данных из @ jezreal Ответит, выход будет

df 
Out[10]: 
    Customer Score 
0 3a62-4000 NaN 
1 3a62-4799 500 
2 3a62-4799 500 
3 3a62-1234 450 
4 3a62-1234 450 
0

К сожалению значений смешиваются иногда NaN первым в повторяющихся строках иногда реальное значение первый.

Мой подход к 100000 рядам работает в течение 30 мин. это немного дольше

X_dup = X.set_index('Customer').index.get_duplicates() 

for l in list(X_dup): 

    up_cust = pd.DataFrame(X[(X['Customer']==l) & (X['Score'] > 0)]) 

    X['Score'][X['Customer']==l ] = up_cust.iloc[0,1] 
Смежные вопросы