仅获取熊猫中一组的很少元素

时间:2019-04-18 04:45:29

标签: python pandas numpy pandas-groupby

我有一个按熊猫分组的数据框:

[index, index, index,...,index] -> [[vec], [vec], [vec]...,[vec]]

这里,每个id都有不同数量的温度记录。

我想修复它们,例如每个id的平均记录数(例如3)。如果缺少某些记录,我想先放入零。

我要保留最近的记录。

即我的最终数据框应该是:

id    date    temperature
1  2011-9-12   12
   2011-9-12   20
   2011-9-18   12
   2011-9-19   90
2  2011-9-12   15
3  2011-9-12   15
   2011-9-16   15

以下是numpy代码,该代码会在网上出现错误:

id    temperature
1     20
      12
      90
2     0
      0
      15
3     0
      15
      15

我怀疑该错误是由于我的数据的ID可以包含3行以上。

如何解决此问题?

2 个答案:

答案 0 :(得分:3)

GroupBy.cumcountascending=False一起用作计数器,并由Series.reindex创建的MultiIndex使用MultiIndex.from_product

print (df)
   id       date  temperature
0   1  2011-9-12           12
1   1  2011-9-12           20
2   1  2011-9-18           12
3   1  2011-9-19           90
4   2  2011-9-12           15
5   3  2011-9-12           15
6   3  2011-9-16           15

N = 3
df['new'] = df.groupby('id').cumcount(ascending=False)
mux = pd.MultiIndex.from_product([df['id'].unique(), range(N-1, -1, -1)], names=['id','new'])
df1 = (df.set_index(['id', 'new'])['temperature']
        .reindex(mux, fill_value=0)
        .reset_index(level=1, drop=True)
        .reset_index())

print (df1)
   id  temperature
0   1           20
1   1           12
2   1           90
3   2            0
4   2            0
5   2           15
6   3            0
7   3           15
8   3           15

编辑:

如果MultiIndex DataFrame

print (df)
              temperature
id date                  
1  2011-9-12           12
   2011-9-12           20
   2011-9-18           12
   2011-9-19           90
2  2011-9-12           15
3  2011-9-12           15
   2011-9-16           15

print (df.index)
MultiIndex(levels=[[1, 2, 3], ['2011-9-12', '2011-9-16', '2011-9-18', '2011-9-19']],
           codes=[[0, 0, 0, 0, 1, 2, 2], [0, 0, 2, 3, 0, 0, 1]],
           names=['id', 'date'])

N = 3
df['new'] = df.groupby('id').cumcount(ascending=False)
mux = pd.MultiIndex.from_product([df.index.levels[0], range(N-1, -1, -1)], names=['id','new'])
df1 = (df.reset_index(level=1, drop=True)
         .set_index('new', append=True)['temperature']
         .reindex(mux, fill_value=0)
         .reset_index(level=1, drop=True)
         .reset_index())

print (df1)
   id  temperature
0   1           20
1   1           12
2   1           90
3   2            0
4   2            0
5   2           15
6   3            0
7   3           15
8   3           15

答案 1 :(得分:2)

一个冗长的解决方案,但是可行:

df.groupby('id').apply(lambda x: x.sort_values(by='date'))
                .drop('id', axis=1)['temperature'].groupby(level=0).tail(3)
                .groupby(level=0).apply(lambda x: np.pad(x, (3-len(x),0), 'constant'))
                .reset_index()

   id   temperature
0   1  [20, 12, 90]
1   2    [0, 0, 15]
2   3   [0, 15, 15]