Pandas group by unique计为新列

时间:2017-03-05 19:51:24

标签: python pandas

我想在我的pandas数据框中添加一个新列select count(distinct ITEM) as col from base_data where STOCK > 0 group by DEPT, CLAS, DATE; ,该列将计算为:

assort_size = base_data[(base_data['STOCK'] > 0)]\
.groupby(['DEPT','CLAS','DATE'])['ITEM']\
.transform('nunique')

我正在做的事情

pandas.core.series.Series

基本上每个部门,班级,日期组合我想获得库存中的物品数量。所以我想要与父数据帧合并,但结果是append (axis=1),所以我不能DEPT, CLAS, DATE它回来(行数不同,例如1.6 M V 1.4 M)。此外,我没有要加入base_data列。我可以在这做什么来逐列获取数据帧?

是否有更好的方法直接在父pandas数据框(assort_size)中创建新列,而不是像创建<p>那样创建新对象?

2 个答案:

答案 0 :(得分:2)

您可以先使用boolean indexing,然后groupby使用nunique并使用join

base_data = pd.DataFrame({"DEPT": ["a", "a", "b", "b"],
                   "CLAS":['d','d','d','d'],
                   "STOCK": [-1, 1, 2,2],
                   "DATE":pd.to_datetime(['2001-10-10','2001-10-10',
                                          '2001-10-10','2001-10-10']),
                   "ITEM":[1,2,3,4]})

print (base_data)
  CLAS       DATE DEPT  ITEM  STOCK
0    d 2001-10-10    a     1     -1
1    d 2001-10-10    a     2      1
2    d 2001-10-10    b     3      2
3    d 2001-10-10    b     4      2

assort_size = base_data[(base_data['STOCK'] > 0)]\
.groupby(['DEPT','CLAS','DATE'])['ITEM'].nunique().rename('n_item')
print (assort_size)
DEPT  CLAS  DATE      
a     d     2001-10-10    1
b     d     2001-10-10    2
Name: n_item, dtype: int64

print (base_data.join(assort_size, on=['DEPT','CLAS','DATE']))
  CLAS       DATE DEPT  ITEM  STOCK  n_item
0    d 2001-10-10    a     1     -1       1
1    d 2001-10-10    a     2      1       1
2    d 2001-10-10    b     3      2       2
3    d 2001-10-10    b     4      2       2

答案 1 :(得分:1)

您可以使用apply代替transform进行复杂计算,并将过滤器移到apply函数中,使用assign为每个组创建一个新列,这将创建一个数据使用新计算的列的框架,不需要任何职位分配:

(base_data.groupby(['DEPT','CLAS','DATE'], group_keys=False)
 .apply(lambda g: g.assign(n_item = g.ITEM[g.STOCK > 0].nunique())))

示例 :(查找C列中唯一值的数量,其中B> 0按A列分组。)

df = pd.DataFrame({"A": ["a", "a", "b", "b"], "B": [-1, 1, 2,2],"C":[1,2,3,4]})

df.groupby('A', group_keys=False).apply(lambda g: g.assign(n_item = g.C[g.B > 0].nunique()))

#   A   B   C   n_item
#0  a  -1   1        1
#1  a   1   2        1
#2  b   2   3        2
#3  b   2   4        2