Python 熊猫按唯一计数分组为新列
我想在我的pandas数据框中添加一个新列Python 熊猫按唯一计数分组为新列,python,pandas,Python,Pandas,我想在我的pandas数据框中添加一个新列col,其计算公式如下: 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('n
col
,其计算公式如下:
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
,因此我无法追加(axis=1)
它(行数不同,例如1.6 M与1.4 M)。此外,我没有要加入的DEPT、CLAS、DATE
列。我可以在这里做些什么来获取带有GROUPBY列的dataframe
是否有更好的方法直接在父数据帧(
base\u data
)中创建新列,而不是像我正在创建的schodk\u size
)那样创建新对象?对于复杂的计算,可以使用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列分组。)
您可以先使用,然后使用groupby
,最后使用:
这行得通,但速度太慢了。对于1.7m行数据帧,我花了大约10多分钟才结束运行。在R data.table I中,通常在几秒钟内完成
base_data 0&EOH_Q>0':='(分类大小=长度(唯一(项目)),by=.(部门、类别、日期)]
,如果性能有问题且没有重复的索引,则可以将计算回原始数据框的分类大小分配为base_data['n_item']=schodk_size
,它将为您对齐索引。我将此与schodk_size=schodk_size.to_frame().reset_index()一起使用
将Pandas.series
转换为Pandas.dataFrame
。这之后的加入速度要快得多。基本上,如果耶茨雷尔回答了一个关于熊猫的问题,那么相信它-这家伙是一个传奇!@ARob4-谢谢。
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
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