Панды или Numpy: как получить соответствующие записи данных, чтобы сделать манипулирование данными - PullRequest
0 голосов
/ 15 декабря 2018

Скажем, например, что у меня есть два отношения данных, например:

Data1:
   C1      C2
"Peter"  "kiwi"
"John"   "banana"
"Susan"  "peach"
"Joe"    "apple"

Data2:
   C3      C4
"apple"     4 
"banana"    7
"apple"     4

Для каждой строки в data1 я хотел бы найти все возможные совпадения в общем атрибуте (скажем, между Data1 [C2] и Data2 [C3]) и суммируют значения Data2 [C4] для всех найденных совпадений.

Конкретнее, к примеру, я хочу, чтобы результирующие вычисления были такими:

"Peter":  0 (no match for "kiwi")
"John":   7 (one match for "banana", it's just 7)
"Susan":  0 (no match for "peach")
"Joe":    8 (two matches for "apple", they're 4+4)

Как я могу добиться этого, эффективно используя pandas dataframe или numpy?

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

1 Ответ

0 голосов
/ 15 декабря 2018

Один способ для пользователя merge и groupby:

data1.merge(data2, left_on='C2', right_on='C3', how='left')[['C1', 'C4']]\
     .fillna(0)\
     .groupby('C1')\
     .sum()

Вывод:

        C1   C4
0    "Joe"  8.0
1   "John"  7.0
2  "Peter"  0.0
3  "Susan"  0.0

Чтобы получить вывод словаря:

data1.merge(data2, left_on='C2', right_on='C3', how='left')[['C1', 'C4']]\
     .fillna(0)\
     .groupby('C1')\
     .sum()\
     .T\
     .to_dict('r')

Вывод:

[{'"Joe"': 8.0, '"John"': 7.0, '"Peter"': 0.0, '"Susan"': 0.0}]

Другой способ - использовать map с sum:

data1['Score'] = data1['C2'].map(data2.set_index('C3', append=True)\
                            .sum(level=1)['C4']).fillna(0)
data1[['C1', 'Score']]

Вывод:

        C1  Score
0  "Peter"    0.0
1   "John"    7.0
2  "Susan"    0.0
3    "Joe"    8.0

Надстройка для комментария:

data1.merge(data2.rename_axis('d2_idx').reset_index(), left_on='C2', right_on='C3', how='left')\
     .groupby('C1')['d2_idx','C4']\
     .agg({'d2_idx':lambda x: ', '.join(x.astype(str)), 'C4':'sum'})

Выход:

           d2_idx   C4
C1                    
"Joe"    0.0, 2.0  8.0
"John"        1.0  7.0
"Peter"       nan  0.0
"Susan"       nan  0.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...