我想在我的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>
那样创建新对象?
答案 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