从操作中排除列而不删除它

时间:2018-12-17 15:54:35

标签: python pandas dataframe

我想在下一个df中使用nan更改所有小于5的值,但是应该从操作中排除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

我可以从df中取出列B,然后将df[df < 5] = np.nan应用于其余的df,然后再次合并它们。在操作之前删除B列也是另一种方法。但我正在寻找一种更有效的方法,如果可能的话,一种班轮。 尝试df[df.columns.difference(['B']) < 5] = np.nan,但不正确。同样df[(df.B != 'Other') < 5] = np.nan也没有成功。

5 个答案:

答案 0 :(得分:3)

让我们使用一个更明智的示例:

                     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

答案 1 :(得分:2)

从您的代码开始,您可以执行以下操作:

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

请注意,df.columns.difference(['B'])是除B以外的列的列表。因此,看看哪个是< 5毫无意义。您首先必须用这些列对数据框进行切片,然后检查条件。最后,您必须添加any来检查是否至少有一个True

答案 2 :(得分:1)

您可以简单地将列切成薄片

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

答案 3 :(得分:1)

您可以使用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

答案 4 :(得分:1)

df[df[df.columns.difference(['B'])]<5]=np.nan