簡體   English   中英

按組和虛擬代碼分類變量透視長格式分類數據

[英]pivot long form categorical data by group and dummy code categorical variables

對於以下數據框,我嘗試將分類變量 ('purchase_item') 轉換為寬格式並將它們虛擬編碼為 1/0 - 基於客戶是否在 2016 年的 4 個季度中的每個季度都購買了它。

在此處輸入圖片說明

我想生成一個旋轉的數據框,如下所示: 在此處輸入圖片說明

為了獲得上面顯示的所需結果,我基本上以各種方式嘗試將 groupby/pivot_table 函數與對 pandas 中的 get_dummies() 函數的調用結合起來。 示例: data.groupby(["cust_id", "purchase_qtr"])["purchase_item"].reset_index().get_dummies()

但是,到目前為止,我的嘗試都沒有奏效。

有人可以幫我生成所需的結果嗎?

一種方法是獲取交叉表,然后強制所有大於 1 的值變為 1,同時保持所有 0 不變:

TL; 博士

out = (
    pd.crosstab([df["cust_id"], df["purchase_qtr"]], df["purchase_item"])
    .gt(0)
    .astype(int)
    .reset_index()
)

打破一切:

創建數據

df = pd.DataFrame({
    "group1": np.repeat(["a", "b", "c"], 4),
    "group2": [1, 2, 3] * 4,
    "item": np.random.choice(["ab", "cd", "ef", "gh", "zx"], size=12)
})

print(df)
   group1  group2 item
0       a       1   cd
1       a       2   ef
2       a       3   gh
3       a       1   ef
4       b       2   zx
5       b       3   ab
6       b       1   ab
7       b       2   gh
8       c       3   gh
9       c       1   cd
10      c       2   ef
11      c       3   gh

交叉制表

這將返回一個頻率表,指示一起觀察每個類別的頻率:

crosstab = pd.crosstab([df["group1"], df["group2"]], df["item"])

print(crosstab)
item           ab  cd  ef  gh  zx
group1 group2
a      1        0   1   1   0   0
       2        0   0   1   0   0
       3        0   0   0   1   0
b      1        1   0   0   0   0
       2        0   0   0   1   1
       3        1   0   0   0   0
c      1        0   1   0   0   0
       2        0   0   1   0   0
       3        0   0   0   2   0

強制計數為虛擬代碼

由於我們想要虛擬代碼,而不是計算類別的共現,我們可以使用一個快速技巧來強制所有大於 0 gt(0)值變為 1 astype(int)

item           ab  cd  ef  gh  zx
group1 group2
a      1        0   1   1   0   0
       2        0   0   1   0   0
       3        0   0   0   1   0
b      1        1   0   0   0   0
       2        0   0   0   1   1
       3        1   0   0   0   0
c      1        0   1   0   0   0
       2        0   0   1   0   0
       3        0   0   0   1   0

您可以通過幾種技巧在一行中完成。

1) 與鑄造為 bool 相結合的唯一索引計數

即使除了indexcolumnsvalues之外沒有任何其他列,也可以在任何情況下工作。 此代碼意味着計算每個索引列交叉點的唯一索引並返回1以防其大於0 else 0

df.reset_index().pivot_table(index=['cust_id','purchase_qtr'], 
                             columns='purchase_item',
                             values='index',
                             aggfunc='nunique', fill_value=0)\
                .astype(bool).astype(int)

2)檢查是否有任何其他列不為空

如果您除了indexcolumnsvalues之外還有其他列,並且希望將它們用於直覺。 就像您的情況下的purchase_date 它更直觀,因為您可以“閱讀”它:如果項目的購買日期不為空,則每季度檢查每個客戶並將它們解析為整數。

df.pivot_table(index=['cust_id','purchase_qtr'],
               columns='purchase_item',values='purchase_date',
               aggfunc=lambda x: all(pd.notna(x)), fill_value=0)\
  .astype(int)

3) 查看落入每個索引列交叉點的len元素

這會看到len元素落在每個索引列交叉點中,並返回1以防其大於0 else 0 同樣直觀的方法:

df.pivot_table(index=['cust_id','purchase_qtr'], 
               columns='purchase_item',
               values='purchase_date',
               aggfunc=len, fill_value=0)\
  .astype(bool).astype(int)

所有返回所需的數據幀:

在此處輸入圖片說明

請注意,當您還沒有數據pivot_table時,您應該只使用crosstab ,因為它pivot_table內部調用pivot_table

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM