2016-10-26 6 views
2

Мне нужно найти, где значения столбцов различаются в заданном кадре данных Pandas.Сравнение значений столбцов в кадре данных Pandas

Я собрал мой dataframe используя методы описания здесь: compare two pandas data frame

Используя этот код, я могу получить добавленные строки и удаленные строки между старым и новым набором данных. Где df1 - старый набор данных, а df2 - новый набор данных. Они имеют одну и ту же схему.

m = df1.merge(df2, on=['ID', 'Name'], how='outer', suffixes=['', '_']) 
adds = m.loc[m.GPA_.notnull() & m.GPA.isnull()] 
deletes = m.loc[m.GPA_.isnull() & m.GPA.notnull()] 

То, что я хочу сделать, это отфильтровать добавляет и удаляет из слитой dataframe затем сравнить значения столбцов, как, например:

for col in m.columns: 
    m["diff_%s" % field] = m[field] != m["%s_" % field] 

Это должно привести к добавлению нескольких логических столбцов, которые проверяют значение изменения. Поэтому мой вопрос: как я могу отфильтровать строки добавления и удаления сначала, прежде чем применять эту логику столбца?

Дополнительная информация:

_data_orig = [ 
[1, "Bob", 3.0], 
[2, "Sam", 2.0], 
[3, "Jane", 4.0]] 
_columns = ["ID", "Name", "GPA"] 

_data_new = [ 
     [1, "Bob", 3.2], 
     [3, "Jane", 3.9], 
     [4, "John", 1.2], 
     [5, "Lisa", 2.2] 
    ] 
_columns = ["ID", "Name", "GPA"] 

df1 = pd.DataFrame(data=_data_orig, columns=_columns) 
df2 = pd.DataFrame(data=_data_new, columns=_columns) 

m = df1.merge(df2, on=['ID', 'Name'], how='outer', suffixes=['', '_']) 
adds = m.loc[m.GPA_.notnull() & m.GPA.isnull()] 
deletes = m.loc[m.GPA_.isnull() & m.GPA.notnull()] 

# TODO: add code to remove adds/deletes here 
# array should now be: [[1, "Bob", 3.2], 
#  [3, "Jane", 3.9]] 
for col in m.columns: 
    m["diff_%s" % field] = m[field] != m["%s_" % field] 
# results in: 
# array with columns ['ID', 'Name', 'GPA', 'Name_', 'GPA_','diff_GPD', 'diff_Name' 
# ... DO other stuff 
# write to csv 
+0

Вы можете добавитьжелаемый результат из ваших данных образца? – jezrael

+0

@jezrael уверен, обновляя сейчас. –

+0

@jezrael код обновлен по запросу –

ответ

3

Вы можете использовать Index.union для concanecate обоих indexes и затем drop строк с idx:

idx = adds.index.union(deletes.index) 
print (idx) 
Int64Index([1, 3, 4], dtype='int64') 

print (m.drop(idx)) 
    ID Name GPA GPA_ 
0 1 Bob 3.0 3.2 
2 3 Jane 4.0 3.9 

Другое решение с boolean indexing:

mask = ~((m.GPA_.notnull() & m.GPA.isnull()) | (m.GPA_.isnull() & m.GPA.notnull())) 
print (mask) 
0  True 
1 False 
2  True 
3 False 
4 False 
dtype: bool 

print (m[mask]) 
    ID Name GPA GPA_ 
0 1 Bob 3.0 3.2 
2 3 Jane 4.0 3.9 
Смежные вопросы