Python pandas - 根据NaN计数阈值删除组

时间:2016-07-25 15:40:34

标签: python pandas

我有一个基于不同气象站的数据集,

stationID | Time | Temperature | ...
----------+------+-------------+-------
123       |  1   |     30      |
123       |  2   |     31      |
202       |  1   |     24      |
202       |  2   |     24.3    |
202       |  3   |     NaN     |
...

我想删除'stationID'组,其中包含超过一定数量的NaN。例如,如果我输入:

**>>> df.groupby('stationID')**

然后,我想删除一组中至少有一定数量的NaN(比如说30个)的组。据我了解,我不能使用dropna(thresh = 10)与groupby:

**>>> df2.groupby('station').dropna(thresh=30)**
*AttributeError: Cannot access callable attribute 'dropna' of 'DataFrameGroupBy' objects...*

那么,使用熊猫最好的方法是什么?

3 个答案:

答案 0 :(得分:3)

IIUC你可以做df2.loc[df2.groupby('station')['Temperature'].filter(lambda x: len(x[pd.isnull(x)] ) < 30).index]

示例:

In [59]:
df = pd.DataFrame({'id':[0,0,0,1,1,1,2,2,2,2], 'val':[1,1,np.nan,1,np.nan,np.nan, 1,1,1,1]})
df

Out[59]:
   id  val
0   0  1.0
1   0  1.0
2   0  NaN
3   1  1.0
4   1  NaN
5   1  NaN
6   2  1.0
7   2  1.0
8   2  1.0
9   2  1.0

In [64]:    
df.loc[df.groupby('id')['val'].filter(lambda x: len(x[pd.isnull(x)] ) < 2).index]

Out[64]:
   id  val
0   0  1.0
1   0  1.0
2   0  NaN
6   2  1.0
7   2  1.0
8   2  1.0
9   2  1.0

因此,这将过滤掉超过1纳米值的组

答案 1 :(得分:0)

您可以创建一个列以通过station_id给出空值的数量,然后使用loc选择相关数据以供进一步处理。

df['station_id_null_count'] = \
    df.groupby('stationID').Temperature.transform(lambda group: group.isnull().sum())
df.loc[df.station_id_null_count > 30, :]  # Select relevant data

答案 2 :(得分:0)

使用@EdChum设置:由于你没有提到你的最终输出,所以添加它。

   vals = df.groupby(['id'])['val'].apply(lambda x: (np.size(x)-x.count()) < 2 ) 

   vals[vals]

   id
   0    True
   2    True
   Name: val, dtype: bool