Панды: сохранить строки уникальные для одной категории - PullRequest
0 голосов
/ 21 мая 2018

У меня есть много категорий с элементами в списках, например так:

colors = ['green', 'red']
animals = ['cat', 'dog']

У меня есть большой фрейм данных, в котором есть все элементы в категориях, например так:

largedf = pd.DataFrame({'arow': ['row1', 'row2', 'row3', 'row4'], 'green': ['a', 'b', 'b', 'a'], 'red': ['a', 'b', 'b', 'a'], 
                   'cat': ['b', 'a', 'b', 'a'], 'dog': ['b', 'a', 'b', 'a']})
    arow    cat dog     green   red
0   row1    b   b       b       a
1   row2    a   a       b       b
2   row3    b   b       b       b
3   row4    a   a       a       a

Я хочусохранить только те строки, где a - это значение для определенной категории и только для этой категории.row3 не будет сохранено, поскольку имеет b для всех элементов, row4 не будет сохранено, поскольку имеет a для всех элементов.

row1 будет сохранено, поскольку оно имеетa для red (хотя для зеленого есть b, по крайней мере, один a находится в этой категории).

row2 будет сохранено, потому что есть хотя бы один a в cat/dog (в этом случае a в обоих).

Для каждой сохраненной строки мне нужен столбец, в котором перечислены категории, в которых есть a и процент a в этой категории (см. Вывод ниже).

shorterdf = pd.DataFrame({'arow': ['row1', 'row2'], 'green': ['a', 'b'], 'red': ['a', 'b'], 'cat': ['b', 'a'], 'dog': ['b', 'a']})
    arow    cat dog     green   red  category   percent
0   row1    b   b       b       a    colors     0.5
1   row2    a   a       b       b    animals    1

Ответы [ 2 ]

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

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

m = {k: (v, k) for k, v in {
        **dict.fromkeys(colors, 'colors'),
        **dict.fromkeys(animals, 'animals')
    }.items()}

largedf[
    largedf.drop('arow', 1)
           .rename(columns=m.get)
           .eq('a').any(axis=1, level=0).sum(1).eq(1)
]

   arow cat dog green red
0  row1   b   b     a   a
1  row2   a   a     b   b

Подробности

df = largedf.drop('arow', 1).rename(columns=m.get)
df

  animals     colors    
      cat dog  green red
0       b   b      a   a
1       a   a      b   b
2       b   b      b   b
3       a   a      a   a

df.eq('a')

  animals        colors       
      cat    dog  green    red
0   False  False   True   True
1    True   True  False  False
2   False  False  False  False
3    True   True   True   True

df.eq('a').any(axis=1, level=0)

   animals  colors
0    False    True
1     True   False
2    False   False
3     True    True

df.eq('a').any(axis=1, level=0).sum(1).eq(1)

0     True
1     True
2    False
3    False
dtype: bool
0 голосов
/ 21 мая 2018

Мы используем nunique, чтобы отфильтровать нужную нам строку.

t=largedf[largedf.iloc[:,1:].nunique(1).gt(1)]

t=t.set_index('arow')
s=t.copy()

Затем мы изменим столбцы на категорию с помощью map

s.columns=s.columns.map(dict(zip(s.columns,np.repeat(['animals','color'],2))).get)

# get the percentage and the category accordingly 
s1=(s.eq('a').groupby(level=0,axis=1).sum()/2).stack()
# concat together 
pd.concat([t,s1[s1!=0].reset_index(level=1)],axis=1).rename(columns={'level_1':'category',0:'percent'})
Out[287]: 
     cat dog green red category  percent
arow                                    
row1   b   b     a   a    color      1.0
row2   a   a     b   b  animals      1.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...