在数据框上使用groupby()后过滤行

时间:2019-07-20 08:52:20

标签: python python-3.x pandas pandas-groupby

我有一个DataFrame(df_not2015),它记录了从2005年到2014年每天的最高和最低温度。

        max   min
day              
01-01  15.6 -16.0
01-02  13.9 -26.7
01-03  13.3 -26.7
01-04  10.6 -26.1
01-05  12.8 -15.0

此DataFrame中有365行,分别对应于一年中的每一天。 (为了便于计算,Le年已被排除)。 我还有另一个DataFrame(df_2015),其中仅包含2015年的温度记录。

             ID        Date   Element   Data_Value
0   USC00205563  2015-01-03      TMIN         -3.9
1   USC00203712  2015-03-17      TMAX         18.9
2   USC00200032  2015-06-06      TMIN         12.8
3   USW00014833  2015-08-30      TMIN         17.8
4   USC00202308  2015-08-30      TMIN         15.6

“ ID”列是记录温度的气象站的ID。由于每天要测量多次温度,因此此DataFrame包含13757行。 TMAX和TMIN指示该温度是该站测得的最高温度还是最低温度。

问题:在第二个DataFrame(df_2015)中,我只想保留特定日期的温度记录中温度高于最大值或低于最小值的那几行,并进行分配例如,假设2015年1月1日的测得温度为[18,16,17,15,14,13,-11,-12,-17,-18],那么我只想保留行值[18,16,17,-17,-18](与第一个DataFrame中的值进行比较),并将这些值保留在“ max”和“ min”的不同列中

示例(不是实际数据)

             ID        Date   Element   Data_Value
0   USC00205563  2015-01-01      TMIN         18
1   USC00203712  2015-01-01      TMAX         16
2   USC00200032  2015-01-01      TMIN         17
3   USW00014833  2015-01-01      TMIN         15
4   USC00202308  2015-01-01      TMIN         14
5   USC00205563  2015-01-01      TMIN         13
6   USC00203712  2015-01-01      TMAX        -11
7   USC00200032  2015-01-01      TMIN        -12
8   USW00014833  2015-01-01      TMIN        -17
9   USC00202308  2015-01-01      TMIN        -18

我正在寻找的中间DataFrame是-

             ID        Date   Element   Data_Value   max     min
0   USC00205563  2015-01-01      TMIN         18      18     Nan
1   USC00203712  2015-01-01      TMAX         16      16     Nan
2   USC00200032  2015-01-01      TMIN         17      17     Nan
3   USW00014833  2015-01-01      TMIN         15      Nan    Nan
4   USC00202308  2015-01-01      TMIN         14      Nan    Nan
5   USC00205563  2015-01-01      TMIN         13      Nan    Nan
6   USC00203712  2015-01-01      TMAX        -11      Nan    Nan
7   USC00200032  2015-01-01      TMIN        -12      Nan    Nan
8   USW00014833  2015-01-01      TMIN        -17      Nan    -17
9   USC00202308  2015-01-01      TMIN        -18      Nan    -18

然后我想删除'max'和'min'均为Nan的行以获得所需的输出-

             ID        Date   Element   Data_Value   max     min
0   USC00205563  2015-01-01      TMIN         18      18     Nan
1   USC00203712  2015-01-01      TMAX         16      16     Nan
2   USC00200032  2015-01-01      TMIN         17      17     Nan
8   USW00014833  2015-01-01      TMIN        -17      Nan    -17
9   USC00202308  2015-01-01      TMIN        -18      Nan    -18

我的方法: 我首先在分配了Nan值的第二个DataFrame('max')和('min')中创建了两个空列。我从“日期”列中删除了“ 2015”(以便“日期”列与df_not2015的索引相同)并按“日期”进行了分组。然后我尝试应用像so-

这样的分组布尔掩码
```python
for name, frame in df_2015.groupby('Date'):
    bool_1 = frame['Data_Value'] > df_not2015.loc[name, 'max']
    bool_2 = frame['Data_Value'] < df_not2015.loc[name, 'min']
    frame.where(bool_1, axis = 1, inplace = True)
    frame.where(bool_2, axis = 1, inplace = True)
```

但是,这会引发警告- SettingWithCopyWarning: 试图在DataFrame的切片副本上设置一个值

当我打印df_2015时,DataFrame中没有变化。这是怎么回事?

此外,遍历各个组似乎并不是很“可恶”。有没有办法做到这一点而无需循环?

1 个答案:

答案 0 :(得分:0)

这是因为您试图更改数据框(df_2015.groupby('Date'))而不是原始数据框(df_2015)的副本,这是在原始数据框中不进行任何更新的相同原因。

尝试这样的事情:

temp_df = df_2015.groupby('Date')   
for name, frame in temp_df:
        bool_1 = frame['Data_Value'] > df_not2015.loc[name, 'max']
        bool_2 = frame['Data_Value'] < df_not2015.loc[name, 'min']
        frame.where(bool_1, axis = 1, inplace = True)
        frame.where(bool_2, axis = 1, inplace = True)

,然后尝试打印temp_df,它将进行更改。

相关问题