我有一个按 Pandas 数据框分组的:
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
这里,每个id有不同数量的温度记录。
我想修复它们,即每个 id 的平均记录数(比如 3)。如果某些记录丢失,我想首先添加零。
我想保留最新的记录。
即我的最终数据框应该是:
id temperature
1 20
12
90
2 0
0
15
3 0
15
15
这是在线给出错误的 numpy 代码:
s=df.groupby(level=0)['temperature'].apply(list)
s1=s.tolist()
arr = np.zeros((len(s1),3),int)
lens = [3-len(l) for l in s1]
mask = np.arange(3) >=np.array(lens)[:,None]
arr[mask] = np.concatenate(s1) ## Error
pd.DataFrame({'id':s.index.repeat(3),'temperature':arr.ravel()})
我怀疑该错误是由于我的数据的 id 可能超过 3 行造成的。
如何解决这个问题?
最佳答案
使用GroupBy.cumcount
计数器为 ascending=False
, Series.reindex
由 MultiIndex.from_product
创建的 MultiIndex
:
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
编辑:
如果多索引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
关于python - 仅获取 Pandas 中的一组元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55739280/