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

У меня есть два кадра данных:

                              NAME      base         RED
3                                %      free        2.00
4                                %   freemem        0.10
5                             sys1   freemem        0.20

и

         NAME
0        sys1
1        sys2

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

Я хочу объединить их вместе, чтобы сформировать перестановки 'base' и 'red' для каждого значения в имени. Важным моментом является то, что если значение из df2.NAME появляется в качестве значения в df1.NAME, то при формировании слияния следует отдавать приоритет этой строке. В противном случае значения 'red' должны быть взяты из строки с именем "%".

Например, для приведенных выше значений я бы хотел, чтобы результат выглядел следующим образом:

   NAME     base   RED
0  sys1     free  2.00
1  sys1  freemem  0.20
2  sys2     free  2.00
3  sys2  freemem  0.10

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

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

1 Ответ

0 голосов
/ 02 мая 2018

Попробуйте следующее:

import pandas as pd
import numpy as np
# Create sample
d = dict()
d['name'] = np.array(['%','%','sys1'])
d['base'] = np.array(['free','freemem','freemem'])
d['red'] = np.array([2,0.1,0.2])
df1 = pd.DataFrame(d)
df1 = df1[['name','base','red']]
df2 = pd.DataFrame(np.array(['sys1','sys2']),columns=['name'])
################################################
part1 = df1[df1['name']!='%']
part2 = pd.DataFrame()
for i in df2.values:
    copy = df1[df1['name']=='%'].copy()
    copy['name'] = np.repeat(i,len(copy['name']) )
    part2 = part2.append(copy)
'''
Part 1:
   name     base  red
2  sys1  freemem  0.2

Part 2:
   name     base  red
0  sys1     free  2.0
1  sys1  freemem  0.1
0  sys2     free  2.0
1  sys2  freemem  0.1
'''
ans = pd.merge(part1,part2, how='outer')
        .drop_duplicates(['name','base'])
print ans.sort_values(['name', 'base'], ascending=[True, True])
Out[]:
   name     base  red
1  sys1     free  2.0
0  sys1  freemem  0.2
3  sys2     free  2.0
4  sys2  freemem  0.1

Поскольку pd.merge(part1,part2, how='outer') поместит part1 выше part2, а команда apply drop_duplicates() удалит повторяющиеся значения в part2. Это не самый простой способ, но он работает. Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...