Удалить конкретные значения в кадре данных в зависимости от того, находятся они в массиве или нет - PullRequest
0 голосов
/ 17 сентября 2018

У меня есть фрейм данных с 2 столбцами, один из которых представляет собой список значений через запятую:

A  1,2,3,4,6

B  1,5,6,7

C  1,3,2,8,9,7

D  1,3,6,8

У меня также есть массив: [2,3,9]

И я бы хотел получить тот же самый фрейм данных, преобразованный таким образом, чтобы значения, не входящие в массив, отфильтровывались. Например:

A  2,3

B  

C  3,2,9

D  3

Может ли кто-нибудь указать мне правильное направление? Я осмотрелся вокруг, но ударил немного стены.

Ответы [ 3 ]

0 голосов
/ 17 сентября 2018

На мой взгляд, метод apply обеспечивает очень удобочитаемое решение.

allowed = [2, 3, 9]
allowed_string = [str(x) for x in allowed]
df[1] = df[1].str.split(',')
df[1] = df[1].apply(lambda x: [y for y in x if y in allowed_string])

Выход:

   0          1
0  A     [2, 3]
1  B         []
2  C  [3, 2, 9]
3  D        [3]
0 голосов
/ 17 сентября 2018

Вы можете подать значения столбцов с помощью метода isin (). см. пример ниже.

import pandas as pd

data = {'A':[1,2,3,4,6],
        'B':[1,5,6,7],
        'C':[1,3,2,8,9,7],
        'D':[1,3,6,8]}

allow_list = [2,3,9]    #list of allowed elements

df = pd.concat([pd.Series(val, name=key) for key, val in data.items()], axis=1)

df1=df[df[df.columns].isin(allow_list)]    #provide list of allowed elements as parameter in isin method
df1.dropna(how='all',inplace=True)    #remove rows which are all NaN
print(df1)

Выход:

     A    C   B    D
1  2.0  3.0 NaN  3.0
2  3.0  2.0 NaN  NaN
4  NaN  9.0 NaN  NaN
0 голосов
/ 17 сентября 2018

Настройка

import re

df = pd.DataFrame({
    'col1': ['A', 'B', 'C', 'D'],
    'col2': ['1,2,3,4,6', '1,5,6,7', '1,3,2,8,9,7', '1,3,6,8']
})

good = [str(i) for i in [2,3,9]]

Мы можем использовать регулярное выражение и re.findall для извлечения всех допустимых значений, мы просто должны утверждать, чтосовпадения не следуют непосредственно или не предшествуют цифре, поэтому мы не сопоставляем цифры в середине другого числа:

rgx = '(?<!\d)({})(?!\d)'.format('|'.join(good))

df.assign(out=[','.join(re.findall(rgx, row)) for row in df.col2])

  col1         col2    out
0    A    1,2,3,4,6    2,3
1    B      1,5,6,7
2    C  1,3,2,8,9,7  3,2,9
3    D      1,3,6,8      3

Regex Объяснение

(?<!                 # Negative lookbehind
  \d                 # Asserts previous character is *not* a digit
)           
(                    # Matching group
  2|3|9              # Matches either 2 or 3 or 9
) 
(?!                  # Negative lookahead
  \d                 # Asserts the following character is *not* a digit
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...