如何对 Pandas (Python) 中的分类数据进行交叉制表?
How to have a cross tabulation for categorical data in Pandas (Python)?
例如,我有以下代码。
df = pd.DataFrame(dtype="category")
df["Gender"]=np.random.randint(2, size=100)
df["Q1"] = np.random.randint(3, size=100)
df["Q2"] = np.random.randint(3, size=100)
df["Q3"] = np.random.randint(3, size=100)
df[["Gender", "Q1", "Q2", "Q3"]] = df[["Gender", "Q1", "Q2", "Q3"]].astype('category')
pd.pivot_table(data=df,index=["Gender"])
我想要一个枢轴 table,其中所有其他列的性别百分比。事实上,就像下面的那样。
如何实现?
上面的代码报错说
No numeric types to aggregate
我没有任何数字列。我只想找到男性和女性下每个类别的频率,并分别找到它们在男性和女性中的百分比。
根据您的问题建议,您可以使用 pd.crosstab
来制作您需要的交叉表。
您只需要对您的数据进行快速 预处理,即 melt
并将 Q
列转换为行(详见下文) :
df = df.melt(id_vars='Gender',
value_vars=['Q1', 'Q2', 'Q3'],
var_name='Question', value_name='Answer' )
然后您可以使用 pd.crosstab
并根据需要计算百分比(此处显示每个 Question
每个 Gender
每个 Answer
的百分比)
pd.crosstab(df.Question, columns=[df.Gender, df.Answer]).apply(lambda row: row/row.sum(), axis=1)
Gender 0 1
Answer 0 1 2 0 1 2
Question
Q1 0.13 0.18 0.18 0.13 0.19 0.19
Q2 0.09 0.21 0.19 0.22 0.13 0.16
Q3 0.19 0.10 0.20 0.16 0.18 0.17
详情
df.head()
Gender Q1 Q2 Q3
0 1 0 2 0
1 1 0 0 1
2 0 2 0 2
3 0 0 2 0
4 0 1 1 1
df.melt().head()
Gender Question Answer
0 1 Q1 0
1 1 Q1 0
2 0 Q1 2
3 0 Q1 0
4 0 Q1 1
例如,我有以下代码。
df = pd.DataFrame(dtype="category")
df["Gender"]=np.random.randint(2, size=100)
df["Q1"] = np.random.randint(3, size=100)
df["Q2"] = np.random.randint(3, size=100)
df["Q3"] = np.random.randint(3, size=100)
df[["Gender", "Q1", "Q2", "Q3"]] = df[["Gender", "Q1", "Q2", "Q3"]].astype('category')
pd.pivot_table(data=df,index=["Gender"])
我想要一个枢轴 table,其中所有其他列的性别百分比。事实上,就像下面的那样。
如何实现?
上面的代码报错说
No numeric types to aggregate
我没有任何数字列。我只想找到男性和女性下每个类别的频率,并分别找到它们在男性和女性中的百分比。
根据您的问题建议,您可以使用 pd.crosstab
来制作您需要的交叉表。
您只需要对您的数据进行快速 预处理,即 melt
并将 Q
列转换为行(详见下文) :
df = df.melt(id_vars='Gender',
value_vars=['Q1', 'Q2', 'Q3'],
var_name='Question', value_name='Answer' )
然后您可以使用 pd.crosstab
并根据需要计算百分比(此处显示每个 Question
每个 Gender
每个 Answer
的百分比)
pd.crosstab(df.Question, columns=[df.Gender, df.Answer]).apply(lambda row: row/row.sum(), axis=1)
Gender 0 1
Answer 0 1 2 0 1 2
Question
Q1 0.13 0.18 0.18 0.13 0.19 0.19
Q2 0.09 0.21 0.19 0.22 0.13 0.16
Q3 0.19 0.10 0.20 0.16 0.18 0.17
详情
df.head()
Gender Q1 Q2 Q3
0 1 0 2 0
1 1 0 0 1
2 0 2 0 2
3 0 0 2 0
4 0 1 1 1
df.melt().head()
Gender Question Answer
0 1 Q1 0
1 1 Q1 0
2 0 Q1 2
3 0 Q1 0
4 0 Q1 1