我正在尝试在Stata中复制非常有用的tabulate twoway
函数,在同一输出中,您可以看到频率,相应的行百分比和数据中两个分类变量的每种可能组合的相应列百分比。
也就是说,结果表中的每个单元格都包含三个与上述数字对应的堆叠值。
Stata中的输出示例:这是单个变量汽车类型的列表,其中,在数据中,我有52个观测值,其中汽车类型为domestic
,22个观测值为汽车类型等于foreign
。
Domestic Foreign Total
52 22 74
70.27 29.73 100.00
100.00 100.00 100.00
在熊猫中可以做到吗?例如:
df = pd.DataFrame({'A' : ['one', 'one', 'two', 'three'] * 6,
'B' : ['A', 'B', 'C'] * 8,
'C' : ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'] * 4,
'D' : np.random.randn(24),
'E' : np.random.randn(24)})
会结合的东西
pd.crosstab(df.A,df.B)
pd.crosstab(df.A, df.B).apply(lambda r: r/r.sum(), axis=1)
和pd.crosstab(df.A, df.B).apply(lambda r: r/r.sum(), axis=0)
在同一输出上。你怎么看?我正在考虑aggfunc
,但在这里我需要获得整个数据帧,而不仅仅是一个系列......
谢谢!
答案 0 :(得分:1)
考虑使用交叉表的margins将所有三个连接成一个df。下面使用您的示例:
newdf = pd.concat([pd.crosstab(df.A, df.B, margins=True),
pd.crosstab(df.A, df.B).apply(lambda r: r/r.sum(), axis=0),
pd.crosstab(df.A, df.B).apply(lambda r: r/r.sum(), axis=1)])
newdf = newdf.loc[['one','two','three','All']] # RE-ORDER INDEX VALUES
newdf = newdf[['A', 'B', 'C', 'All']] # RE-ORDER COLUMNS
newdf['All'] = np.where(pd.isnull(newdf['All']) & # ROW PERCENTAGES SUM
(newdf['A'] + newdf['B'] + newdf['C']==1),
1, newdf['All'])
print(newdf)
# A B C All
# A
# one 4.000000 4.000000 4.000000 12.0
# one 0.500000 0.500000 0.500000 NaN
# one 0.333333 0.333333 0.333333 1.0
# two 2.000000 2.000000 2.000000 6.0
# two 0.250000 0.250000 0.250000 NaN
# two 0.333333 0.333333 0.333333 1.0
# three 2.000000 2.000000 2.000000 6.0
# three 0.250000 0.250000 0.250000 NaN
# three 0.333333 0.333333 0.333333 1.0
# All 8.000000 8.000000 8.000000 24.0