[英]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 不變:
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
您可以通過幾種技巧在一行中完成。
即使除了index
、 columns
和values
之外沒有任何其他列,也可以在任何情況下工作。 此代碼意味着計算每個索引列交叉點的唯一索引並返回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)
如果您除了index
、 columns
和values
之外還有其他列,並且希望將它們用於直覺。 就像您的情況下的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)
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.