2016-10-22 8 views
1

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 У меня есть два кадра данных. Оба столбца X имеют значения SHA2. Он содержит шестнадцатеричные строки.Pandas merge дает неправильный результат

Пример (Dataframe поиск)

X,Y 
000000000E000394574D69637264736F66742057696E646F7773204861726477,7 
0000000080000000000000090099000000040005000000000000008F2A000010,7 
000000020000000000000000777700010000000000020000000040C002004600,24 
0000005BC614437F6BE049237FA1DDD2083B5BA43A10175E4377A59839DC2B64,7 

Пример (источник Dataframe)

X,Z 
000000000E000394574D69637264736F66742057696E646F7773204861726477,'blah' 
0000000080000000000000090099000000040005000000000000008F2A000010,'blah blah' 
000000020000000000000000777700010000000000020000000040C002004600,'dummy' 

т.д.

Так что теперь я делаю

lookup['X'] = lookup['X'].astype(str) 
source['X'] = source['X'].astype(str) 
source['newcolumn'] = source.merge(lookup, on='X', how='inner')['Y'] 

Источник имеет 160000 строк и поиск имеет около 500 000 строк.

Теперь, когда операция завершается, я получаю newcolumn, но значения неправильные. Я убедился, что они не подбираются из повторяющихся значений X, потому что в любой таблице нет дубликата X.

Таким образом, это действительно заставляет меня чувствовать себя глупым и причинять мне большую боль в моих живых системах. Может ли кто-нибудь предположить, в чем проблема?

Теперь я заменил вызов с

def getReputation(lookupDF,value,lookupcolumn,default): 
    lookupRows = lookupDF.loc[lookupDF['X']==value] 
    if lookupRows.shape[0]>0: 
     return lookupRows[lookupcolumn].values[0] 
    else: 
     return default 

source['newcolumn'] = source.apply(lambda x: getReputation(lookup,x['X'],'Y',-1),axis=1) 

Этот код работает - но очевидно, что это плохой код и занимает ужасное долгое время. Я могу многопроцессорствовать, но вопрос остается. ПОЧЕМУ это слияние?

Спасибо за вашу помощь Rgds

ответ

3

Я хотел бы использовать map() метод в данном случае:

первого набора 'X' в качестве индекса в lookup DF:

In [58]: lookup.set_index('X', inplace=True) 

In [59]: lookup 
Out[59]: 
                    Y 
X 
000000000E000394574D69637264736F66742057696E646F7773204861726477 7 
0000000080000000000000090099000000040005000000000000008F2A000010 7 
000000020000000000000000777700010000000000020000000040C002004600 24 
0000005BC614437F6BE049237FA1DDD2083B5BA43A10175E4377A59839DC2B64 7 

In [60]: df['Y'] = df.X.map(lookup.Y) 

In [61]: df 
Out[61]: 
                    X   Z Y 
0 000000000E000394574D69637264736F66742057696E646F7773204861726477  blah 7 
1 0000000080000000000000090099000000040005000000000000008F2A000010 blah blah 7 
2 000000020000000000000000777700010000000000020000000040C002004600  dummy 24 

На самом деле код работает правильно для вашего образца. DF:

In [68]: df.merge(lookup, on='X', how='inner') 
Out[68]: 
                    X   Z Y 
0 000000000E000394574D69637264736F66742057696E646F7773204861726477  blah 7 
1 0000000080000000000000090099000000040005000000000000008F2A000010 blah blah 7 
2 000000020000000000000000777700010000000000020000000040C002004600  dummy 24 

Итак, проверьте, есть ли у вас одинаковые данные и типы в столбце X в обоих DF

+0

Привет, спасибо за этот комментарий. Я проверю карту и вернусь как можно скорее. – Run2

+0

Это работало как шарм. Благодарю. И НЕТ - я ничего не изменил. Таким образом, есть проблема с объединением. Может быть, я должен сообщить об ошибке. И да, я удостоверяюсь, что dtype и данные совпадают до слияния. Он работает на этих нескольких строках, но не на реальных наборах данных, которые довольно велики. – Run2

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