Поменяйте местами значения двух столбцов данных, если применяются условия (Python 3) - PullRequest
0 голосов
/ 28 ноября 2018

Я хочу рассчитать среднее значение countX для всех строк, которые имеют похожие адреса1 и адреса2, или для случаев, когда значения адреса инвертированы.То есть address1 = ad3 и address2 = ad1 аналогичны address1 = ad1 и address2 = ad3.

Например, если входные данные (файл CSV):

ID    COUNTX     ADDRESS1     ADDRESS2  
1        21       ad3       ad1
2        22       ad1       ad3
3        23       ad2       ad4
4        25       ad2       ad4
5        25       ad1       ad5
6        23       ad5       ad1
7        22       ad1       ad4
8        21       ad4       ad6  

Выходные данныедолжно быть:

ID    COUNTX     ADDRESS1     ADDRESS2     AVG_cOUNTX   
1        21       ad3       ad1       21.5
3        23       ad2       ad4       24
5        25       ad1       ad5       24
7        22       ad1       ad4       22
8        21       ad4       ad6       21

Я пытался сделать следующее:

  1. Использовать вложенный цикл, чтобы поменять значения столбцов, когда я обнаружу, что address1_of_a_row = address2_another_row и address2_of_a_row = address1_another_row
  2. Сгруппируйте по адресу1 и адресу2 и рассчитайте AVG.

Поскольку у меня большие наборы данных (1-3 миллиона), это должно быть очень эффективно (что не так для моегокод).

Я использую Python 3.7 и пакет pandas 0.22.Любые отзывы будут оценены.

1 Ответ

0 голосов
/ 28 ноября 2018

Вот один из способов.Могут быть и другие, более элегантные решения, но это должно сработать и будет гораздо более эффективным, чем вложенный цикл.

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

df['ADDRESS_1'] = df[['ADDRESS1', 'ADDRESS2']].values.min(axis=1)
df['ADDRESS_2'] = df[['ADDRESS1', 'ADDRESS2']].values.max(axis=1)

Затем используйте groupby:

grouped = df.groupby(['ADDRESS_1', 'ADDRESS_2']).mean()[['COUNTX']].reset_index()

Результаты:

  ADDRESS_1 ADDRESS_2  COUNTX
0       ad1       ad3    21.5
1       ad1       ad4    22.0
2       ad1       ad5    24.0
3       ad2       ad4    24.0
4       ad4       ad6    21.0

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

...