pandas DataFrame:在重复的ID块中的集合值。

问题描述 投票:0回答:1

给定一个有ID列和相应值列的DataFrame,我如何在重复ID的块中聚合(比如说求和)值?

示例DF。

import numpy as np
import pandas as pd

df = pd.DataFrame(
    {'id': ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'a', 'a', 'b', 'a', 'b', 'b', 'b'],
     'v': np.ones(15)}
    )

请注意,只有两个唯一的ID,所以一个简单的... groupby('id') 不会用。而且,IDs也不会有规律地交替重复。我想出的办法是重新创建索引,来表示改变了的ID的块。

# where id changes:
m = [True] + list(df['id'].values[:-1] != df['id'].values[1:])

# generate a new index from m:
idx, i = [], -1
for b in m:
    if b:
        i += 1
    idx.append(i)

# set as index:
df = df.set_index(np.array(idx))

# now I can use groupby:
df.groupby(df.index)['v'].sum()
# 0    5.0
# 1    3.0
# 2    2.0
# 3    1.0
# 4    1.0
# 5    3.0

这种重新创建索引的方法,让人感觉有点... 殊不知 pandas. 我错过了什么?有没有更好的方法?

python pandas dataframe group-by aggregate
1个回答
2
投票

这里需要创建辅助程序 Series 与比较移位值的不等式比较 ne 累计金额,并传递给 groupby,因为 id 列表中的列可以一起传递,将第一级的MultiIndex由第一级删除。reset_index(level=0, drop=True) 然后将索引转换为列 id:

print (df['id'].ne(df['id'].shift()).cumsum())
0     1
1     1
2     1
3     1
4     1
5     2
6     2
7     2
8     3
9     3
10    4
11    5
12    6
13    6
14    6
Name: id, dtype: int32

df1 = (df.groupby([df['id'].ne(df['id'].shift()).cumsum(), 'id'])['v'].sum()
          .reset_index(level=0, drop=True)
          .reset_index())
print (df1)
  id    v
0  a  5.0
1  b  3.0
2  a  2.0
3  b  1.0
4  a  1.0
5  b  3.0

另一个想法是使用GroupBy.agg 词条和合计 id 逐列 GroupBy.first:

df1 = (df.groupby(df['id'].ne(df['id'].shift()).cumsum(), as_index=False)
         .agg({'id':'first', 'v':'sum'}))
© www.soinside.com 2019 - 2024. All rights reserved.