2017-03-05 45 views
1

我想在我的熊貓數據幀中添加一個新列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出現,所以我不能append (axis=1)它回來(行數不同,例如1.6 M Vs 1.4 M)。另外我沒有DEPT, CLAS, DATE列加入。我可以在這裏做什麼來獲得按列分組的數據框?

有沒有更好的方法直接在父熊貓數據框(base_data)中創建新列,而不是創建一個新對象,比如我正在創建assort_size

回答

1

您可以ü SE boolean indexing第一,然後用nunique和最後joingroupby

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 
+0

我用'assort_size = assort_size.to_frame()。reset_index()'將Pandas.series轉換爲'Pandas.dataFrame'。接下來的加入速度要快得多。 – abhiieor

1

可以使用apply,而不是transform複雜計算和移動過濾器的應用函數裏面,用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 
+0

這工作,但它是該死的慢。對於1.7 M行數據幀,在我殺死遊戲之前花費了大約10多分鐘。在R data.table中,我用來做'base_data < - base_data [BOH_Q> 0&EOH_Q> 0,':='(assort_size = length(unique(ITEM))),by =。(DEPT,CLAS,DATE)]過去幾秒鐘內就完成了。 – abhiieor

+0

如果性能問題且沒有重複索引,則可以將計算的'assort_size'指定回原始數據框爲'base_data ['n_item'] = assort_size',它將爲您匹配索引。 – Psidom