Исключение столбца из операции без его удаления - PullRequest
0 голосов
/ 17 декабря 2018

Я хочу изменить все значения меньше 5 в следующем df с nan, но столбец B следует исключить из операции, не удаляя его.

                    A   B   C   D
DateTime                
2016-03-03 05:45:00 1   2   3   4
2016-03-03 06:00:00 1   2   3   4
2016-03-03 06:15:00 1   2   3   4
2016-03-03 06:30:00 1   2   3   4
2016-03-03 06:45:00 1   2   3   4

желаемый результат

                    A   B   C   D
DateTime                
2016-03-03 05:45:00 NaN 2   NaN NaN
2016-03-03 06:00:00 NaN 2   NaN NaN
2016-03-03 06:15:00 NaN 2   NaN NaN
2016-03-03 06:30:00 NaN 2   NaN NaN
2016-03-03 06:45:00 NaN 2   NaN NaN

Я могу взять столбец B из df, затем применить df[df < 5] = np.nan к оставшемуся df, затем снова объединить их.Удаление столбца B перед операцией также может быть другим подходом.Но я ищу более эффективный способ, один лайнер, если это возможно.Пытаюсь df[df.columns.difference(['B']) < 5] = np.nan, но это не правильно.Также df[(df.B != 'Other') < 5] = np.nan без успеха.

Ответы [ 5 ]

0 голосов
/ 17 декабря 2018
df[df[df.columns.difference(['B'])]<5]=np.nan
0 голосов
/ 17 декабря 2018

Давайте рассмотрим более разумный пример:

                     A  B  C   D
DateTime                        
2016-03-03 05:45:00  1  2  3   4
2016-03-03 06:00:00  1  2  3  10
2016-03-03 06:15:00  1  2  6   4
2016-03-03 06:30:00  1  2  3   4
2016-03-03 06:45:00  1  2  6  10

df.loc[:, df.columns.difference(['B'])] = df[df >= 5] 
df
                      A  B    C     D
DateTime                             
2016-03-03 05:45:00 NaN  2  NaN   NaN
2016-03-03 06:00:00 NaN  2  NaN  10.0
2016-03-03 06:15:00 NaN  2  6.0   NaN
2016-03-03 06:30:00 NaN  2  NaN   NaN
2016-03-03 06:45:00 NaN  2  6.0  10.0

Это маскирует все, но присваивает только на основе loc.


Другой вариантмаскировка с помощью update:

v = df[df >= 5]
v.update(df[['B']])

                      A    B    C     D
DateTime                               
2016-03-03 05:45:00 NaN  2.0  NaN   NaN
2016-03-03 06:00:00 NaN  2.0  NaN  10.0
2016-03-03 06:15:00 NaN  2.0  6.0   NaN
2016-03-03 06:30:00 NaN  2.0  NaN   NaN
2016-03-03 06:45:00 NaN  2.0  6.0  10.0
0 голосов
/ 17 декабря 2018

Работая из своего кода, вы можете вместо этого:

mask = (df.loc[:,df.columns.difference(['B']).tolist()] < 5).any()
df[mask[mask].index] = np.nan

Обратите внимание, что df.columns.difference(['B']) - это список столбцов, исключая B.Так что не имеет смысла видеть, какие из них < 5.Сначала нужно нарезать кадр данных с этими столбцами, чтобы затем проверить соответствие.Наконец, вы должны добавить any, чтобы проверить, есть ли хотя бы True.

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

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

df.mask(df.lt(5)).combine_first(df[['B']])

Out[258]: 
                     A    B   C   D
DateTime                           
2016-03-0305:45:00 NaN  2.0 NaN NaN
2016-03-0306:00:00 NaN  2.0 NaN NaN
2016-03-0306:15:00 NaN  2.0 NaN NaN
2016-03-0306:30:00 NaN  2.0 NaN NaN
2016-03-0306:45:00 NaN  2.0 NaN NaN
0 голосов
/ 17 декабря 2018

Вы можете сделать это, просто разрезая столбцы

import pandas as pd
import numpy as np
df = pd.DataFrame({l:range(10) for l in 'ABCDEFGH'})

dont_change=['B']

cols = [col for col in df.columns if col not in dont_change]

df_sel = df.loc[:,cols] # select correct columns
df_sel[df_sel<5]=np.nan # modify
df[cols]=df_sel #reassign
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...