Python-熊猫-根据行平均值过滤出列

时间:2018-07-22 18:58:57

标签: python pandas dataframe

我有一个包含几列和一个日期索引的DataFrame:

TIME           A         B          C              D              E 
---------------------------------------------------------------------    
2015-03-01   0.74      -0.70       2.62           2.64           3.43   
2015-03-02   0.15      -1.28       0.56           400.58         0.08   
2015-03-03  -0.18      -3.82       0.21           0.22          -0.32   
2015-03-04  -1.45      -1.26       0.74           0.76          -0.09   
2015-03-05 -13.01     -12.88     -16.46         -16.45         -11.67   
2015-03-06 -47.73     -57.09     -55.45         -55.51         -55.15   
2015-03-07  -2.31      -3.57     -36.24         -39.50           2.87   
2015-03-08   0.64       0.34       1.76           1.75           1.51   

我想删除任何具有至少一个条目的列,该列的值不在行平均值的100之内。

换句话说,如果日期2015-03-02的所有列的平均值为80.018,那么我只想保留该特定日期的值在-19.982和180.018之间的列。因此,在此示例中,我将排除列D,因为它的值超出该范围。

我也不想遍历数据框的行,因此我正在寻找一种非常Python化的解决方案。

1 个答案:

答案 0 :(得分:1)

我认为需要:

#if necessary create DatetimeIndex
df = df.set_index('TIME')

#get mean per rows
s = df.mean(axis=1)
#create boolean mask by +/- 100 chained by OR (|)
m = (df.gt(s + 100, axis=0) ) | (df.lt(s - 100, axis=0))

#remove column by condition - inverted mask with any for check at least one True
df = df.loc[:, ~m.any()]
print (df)
                A      B      C      E
TIME                                  
2015-03-01   0.74  -0.70   2.62   3.43
2015-03-02   0.15  -1.28   0.56   0.08
2015-03-03  -0.18  -3.82   0.21  -0.32
2015-03-04  -1.45  -1.26   0.74  -0.09
2015-03-05 -13.01 -12.88 -16.46 -11.67
2015-03-06 -47.73 -57.09 -55.45 -55.15
2015-03-07  -2.31  -3.57 -36.24   2.87
2015-03-08   0.64   0.34   1.76   1.51

详细信息

print (m)
                A      B      C      D      E
TIME                                         
2015-03-01  False  False  False  False  False
2015-03-02  False  False  False   True  False
2015-03-03  False  False  False  False  False
2015-03-04  False  False  False  False  False
2015-03-05  False  False  False  False  False
2015-03-06  False  False  False  False  False
2015-03-07  False  False  False  False  False
2015-03-08  False  False  False  False  False

另一种解决方案:

m = (df.lt(s + 100, axis=0) ) & (df.gt(s - 100, axis=0))

#check all Trues per columns
df = df.loc[:, m.all()]

print (m)
               A     B     C      D     E
TIME                                     
2015-03-01  True  True  True   True  True
2015-03-02  True  True  True  False  True
2015-03-03  True  True  True   True  True
2015-03-04  True  True  True   True  True
2015-03-05  True  True  True   True  True
2015-03-06  True  True  True   True  True
2015-03-07  True  True  True   True  True
2015-03-08  True  True  True   True  True