Как удалить строки со значениями 51% + NaN на основе подсчета из другого столбца - PullRequest
2 голосов
/ 05 ноября 2019

Я хочу удалить строки, в которых мое целевое значение больше нуля более 25% времени с условием 25%, примененным к другому столбцу. В качестве альтернативы я мог бы придумать пороговое значение, так как максимальное число раз NaN является приемлемым, но опять же на основе значения другого столбца.

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

Мой фрейм данных намного больше, но примерно такой - предположим, что 50% значений 'a3', соответствующих col ['aid'], равны нулю в col ['T ']

df = pd.DataFrame([[1,'a1','c1', 111],
                   [2,'a2','c3', 222],
                   [3,'a3','c3',],
                   [4,'a1','c5', 444],
                   [5,'a3','c4',],
                   [6,'a3','c5', 666],
                   [7,'a3','c3', 777]], columns=['pid','aid','cid','T'])
df
   pid aid cid      T
0    1  a1  c1  111.0
1    2  a2  c3  222.0
2    3  a3  c3    NaN
3    4  a1  c5  444.0
4    5  a3  c4    NaN
5    6  a3  c5  666.0
6    7  a3  c3  777.0

Я пробовал

df.dropna(thresh=0.25*(df['aid'].value_counts()), axis = 1)

мой желаемый вывод при пороге 25% равен

   pid aid cid      T
0    1  a1  c1  111.0
1    2  a2  c3  222.0
3    4  a1  c5  444.0
5    6  a3  c5  666.0
6    7  a3  c3  777.0

при пороге 51% моего кадра данныхбудет без изменений

   pid aid cid      T
0    1  a1  c1  111.0
1    2  a2  c3  222.0
2    3  a3  c3    NaN
3    4  a1  c5  444.0
4    5  a3  c4    NaN
5    6  a3  c5  666.0
6    7  a3  c3  777.0

любой совет будет оценен

Ответы [ 2 ]

2 голосов
/ 05 ноября 2019

Вы можете использовать transform

s=df['T'].isnull().groupby(df['aid']).transform('mean')
n=0.25
df.loc[(s<=n)|(df['T'].notnull()),]
Out[39]: 
   pid aid cid      T
0    1  a1  c1  111.0
1    2  a2  c3  222.0
3    4  a1  c5  444.0
5    6  a3  c5  666.0
6    7  a3  c3  777.0
0 голосов
/ 05 ноября 2019

Я бы сделал

thresh = .50
if len(df.query("aid=='a3' and T != T").index) / len(df.index) > thresh:
    df = df.dropna(subset=['T'])

или, если вам не нравится синтаксис запроса,

thresh = .50
if len(df[(df['aid'] == 'a3') & (df['T'].isna())].index) / len(df.index) > thresh:
    df = df.dropna(subset=['T'])

версия maxcount:

maxcount = 2
if len(df[(df['aid'] == 'a3') & (df['T'].isna())].index) > maxcount:
    df = df.dropna(subset=['T'])

[править] Поскольку яне хватает представителя, чтобы прокомментировать ответ WeNYoBen, вот версия их ответа maxcount с большим количеством имен питонических переменных:

aid_var_null_ct = df['T'].isnull().groupby(df['aid']).transform('sum')
thresh = 1
df.loc[(aid_var_null_ct <= thresh) | (df['T'].notnull()),]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...