2013-09-09 6 views
3

Я относительно новичок в python, но я использовал Wes Kinney's «Python for Data Analysis» религиозно в течение последних нескольких недель. Я потратил часы, пытаясь найти решение моей текущей проблемы, но мне нужна помощь. Однако у меня есть набор данных, содержащий данные для отправок, отправленных в этом календарном году; поскольку я получаю новые данные каждый месяц, некоторые детали могут быть изменены. Я выяснил, как идентифицировать измененные отправления, а также как определить, какие изменения могут быть.Подсчет сходства между двумя кадрами данных pandas

Итак, допустим, я определил, что эти поставки (в dataframe, оригинал) изменились:

ID  Code Mode Amount From  To  Weight Cube Service_Date 
MNO123 BBB  Air  50  M1234 M9876 60  6  1-1-2013 
GHI123 AAA  Air  50  M1234 M9876 80  8  1-1-2013 
JKL123 AAA  Ship 50  M1234 M9876 70  7  1-1-2013 

И я определил возможные изменения (в dataframe, изменения), как:

ID  Code Mode Amount From  To  Weight Cube Service_Date 
MNO123 BBB  Air  50  M1234 M9876 60  6  2-2-2013 
MNO123 BBB  Air  60  M1234 M9876 60  6  2-2-2013 
MNO123 BBB  Air  70  M1234 M1111 60  6  2-2-2013 
GHI123 AAA  Air  65  M1234 M9876 80  8  1-1-2013 
JKL123 AAA  Ship 65  M1234 M9876 70  7  1-1-2013 
JKL123 AAA  Ship 65  M1234 M9876 70  8  1-1-2013 

Все, что я пытаюсь сделать, это добавить столбец count к изменениям dataframe, который суммирует количество значений, соответствующих соответствующим значениям в исходном фрейме. Поэтому, поскольку соответствие кода, режима, количества, от, до, веса и куба, столбец count получит значение 7 для первого наблюдения. Аналогичным образом, но имеющие один меньше соответствующее значение, второе наблюдение будет иметь значение счетчика 6, а третий будет иметь значение счетчика 5.

Результат Ищу выглядит следующим образом:

ID  Code Mode Amount From  To  Weight Cube Service_Date Count 
MNO123 BBB  Air  50  M1234 M9876 60  6  2-2-2013  7 
MNO123 BBB  Air  60  M1234 M9876 60  6  2-2-2013  6 
MNO123 BBB  Air  70  M1234 M1111 60  6  2-2-2013  5 
GHI123 AAA  Air  65  M1234 M9876 80  8  1-1-2013  7 
JKL123 AAA  Ship 65  M1234 M9876 70  7  1-1-2013  7 
JKL123 AAA  Ship 65  M1234 M9876 70  8  1-1-2013  6 

Пройдя через книгу Уэса и многочисленные несколько похожие сообщения на этом сайте, я считаю, что мне нужно использовать df.iterrows(), но я борюсь с процессом, чтобы перебирать оба кадра данных, а также проверять и подсчитывать соответствующие значения.

Это была моя последняя попытка:

for i in changes.iterrows(): 
    for i in original.iterrows(): 
    changes['count'] = 0 
    if changes(i) == original(i): 
     changes['count'] +=1 

Заранее спасибо за ваше время и усилия!

+0

Этот фрагмент кода не работает, поскольку счетчик сбрасывается во время каждой исходной строки. –

+0

Можете ли вы привести пример с DataFrame с более чем одной строкой, неясно, будет ли это работать (как, например, я говорю, ваш пример кода не), и каков должен быть результат. –

+0

@ AndyHayden, я добавил дополнительные строки в оба DataFrames, а также добавил результат, который я ищу. Сообщите мне, есть ли что-нибудь еще, что я могу сделать, чтобы помочь вам помочь. –

ответ

1

Вот один из способов:

Убедитесь, что вы установите индекс как оригинальный и изменения DataFrames быть ID:

In [11]: orignal.set_index('ID', inplace=True) 

In [12]: original 
Out[12]: 
     Code Mode Amount From  To Weight Cube Service_Date 
ID                 
MNO123 BBB Air  50 M1234 M9876  60  6  1-1-2013 
GHI123 AAA Air  50 M1234 M9876  80  8  1-1-2013 
JKL123 AAA Ship  50 M1234 M9876  70  7  1-1-2013 

Вам также придется немного взломать здесь, чтобы мы могли использовать метод eq DataFrame, к сожалению, это делает сортировку (или вы можете отслеживать оригинальный уникальный индекс).

In [13]: changes = changes.set_index('ID').sort_index() 

Выберите столбцы, которые вы заинтересованы в (в качестве альтернативы можно просто опустить колонку Service_Date):

In [14]: count_columns = ['Code', 'Mode', 'Amount', 'From', 'To', 'Weight', 'Cube'] 

Затем вы можете использовать метод эк DataFrame:

In [15]: changes.eq(original)[count_columns] 
Out[15]: 
     Code Mode Amount From  To Weight Cube 
ID             
GHI123 True True False True True True True 
JKL123 True True False True True True True 
JKL123 True True False True True True False 
MNO123 True True True True True True True 
MNO123 True True False True True True True 
MNO123 True True False True False True True 

и сумму каждый ряд:

In [16]: changes.eq(original)[count_columns].sum(1) 
Out[16]: 
ID 
GHI123 6 
JKL123 6 
JKL123 5 
MNO123 7 
MNO123 6 
MNO123 5 
dtype: int64 

In [17]: changes['match'] = changes.eq(original)[count_columns].sum(1).values 

In [18]: changes 
Out[18]: 
     Code Mode Amount From  To Weight Cube Service_Date match 
ID                  
GHI123 AAA Air  65 M1234 M9876  80  8  1-1-2013  6 
JKL123 AAA Ship  65 M1234 M9876  70  7  1-1-2013  6 
JKL123 AAA Ship  65 M1234 M9876  70  8  1-1-2013  5 
MNO123 BBB Air  50 M1234 M9876  60  6  2-2-2013  7 
MNO123 BBB Air  60 M1234 M9876  60  6  2-2-2013  6 
MNO123 BBB Air  70 M1234 M1111  60  6  2-2-2013  5 

Примечание: количество показаний немного отличается от ваших ...

+0

Это прекрасно работает. Очень ценим! –

0

Вам не нужно перебирать строки:

def count_equal(row, original, ID): 
    """Counts the number of equal elements between row and original.ix[ID]""" 
    equal_values = (row == original[original.ID == ID]).values 
    return equal_values.sum() - 1 # substract 1 because ID doesn't count 

changes['count'] = changes.apply(count_equal, args=(original, 'MNO123'), axis=1) 
+0

Хотя это работает, и я ценю вашу помощь, я отредактировал свой оригинальный вопрос, чтобы показать, что «MNO123» - не единственный идентификатор. Как мне изменить ваш ответ, чтобы включить меняющиеся значения идентификатора? Еще раз спасибо. –

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