在 Pandas 中是不是有一种 pythonic 的方法来做一个列联表?
Posted
技术标签:
【中文标题】在 Pandas 中是不是有一种 pythonic 的方法来做一个列联表?【英文标题】:Is there a pythonic way to do a contingency table in Pandas?在 Pandas 中是否有一种 pythonic 的方法来做一个列联表? 【发布时间】:2015-07-06 05:48:51 【问题描述】:给定一个如下所示的数据框:
A B
2005-09-06 5 -2
2005-09-07 -1 3
2005-09-08 4 5
2005-09-09 -8 2
2005-09-10 -2 -5
2005-09-11 -7 9
2005-09-12 2 8
2005-09-13 6 -5
2005-09-14 6 -5
有没有像这样创建 2x2 矩阵的 Pythonic 方法:
1 0
1 a b
0 c d
地点:
a = A 列和 B 列的对应元素均为正数的 obs 数。
b = B 列中 A 列对应元素为正数和负数的 obs 数。
c = obs 的数量,其中 A 列的相应元素在 B 列中为负数和正数。
d = A 列和 B 列对应元素均为负数的 obs 数。
对于本例,输出将是:
1 0
1 2 3
0 3 1
谢谢
【问题讨论】:
【参考方案1】:使用 pandas 函数crosstab
可能是最简单的。借用上面的Dyno Fu:
import pandas as pd
from StringIO import StringIO
table = """dt A B
2005-09-06 5 -2
2005-09-07 -1 3
2005-09-08 4 5
2005-09-09 -8 2
2005-09-10 -2 -5
2005-09-11 -7 9
2005-09-12 2 8
2005-09-13 6 -5
2005-09-14 6 -5
"""
sio = StringIO(table)
df = pd.read_table(sio, sep=r"\s+", parse_dates=['dt'])
df.set_index("dt", inplace=True)
pd.crosstab(df.A > 0, df.B > 0)
输出:
B False True
A
False 1 3
True 3 2
[2 rows x 2 columns]
如果您想使用 scipy.stats
等进行 Fisher 精确检验,也可以使用该表:
from scipy.stats import fisher_exact
tab = pd.crosstab(df.A > 0, df.B > 0)
fisher_exact(tab)
【讨论】:
谢谢!感谢您的努力。【参考方案2】:让我们将您的数据框称为data
。试试
a = data['A']>0
b = data['B']>0
data.groupby([a,b]).count()
【讨论】:
谁否决了这个答案:请发表评论 - 为什么。 这个答案创建了一个具有两个索引的数据框,而不是所需的列联表格式,其中这两个索引分别位于 X 和 Y 轴上【参考方案3】:这是一个关于 pandas 交叉表功能的非常有用的页面:
https://chrisalbon.com/python/data_wrangling/pandas_crosstabs/
所以我认为你应该使用你想做的事
import pandas as pd
pd.crosstab(data['A']>0, data['B']>0)
希望有帮助!
【讨论】:
更新链接(我认为)chrisalbon.com/python/data_wrangling/pandas_crosstabs【参考方案4】:import pandas as pd
from StringIO import StringIO
table = """dt A B
2005-09-06 5 -2
2005-09-07 -1 3
2005-09-08 4 5
2005-09-09 -8 2
2005-09-10 -2 -5
2005-09-11 -7 9
2005-09-12 2 8
2005-09-13 6 -5
2005-09-14 6 -5
"""
sio = StringIO(table)
df = pd.read_table(sio, sep=r"\s+", parse_dates=['dt'])
df.set_index("dt", inplace=True)
a = df['A'] > 0
b = df['B'] > 0
df1 = df.groupby([a,b]).count()
print df1["A"].unstack()
输出:
B False True
A
False 1 3
True 3 2
这只是 lnanenok 的回答,并使用 unstack()
使其更具可读性。功劳应该归于lanenok。
【讨论】:
以上是关于在 Pandas 中是不是有一种 pythonic 的方法来做一个列联表?的主要内容,如果未能解决你的问题,请参考以下文章
在 Python 中,是不是有一种方便的方法来重载 C++ 中的方法? [复制]
是否有一种功能可以在维持我的订单的同时将我的数字在 pandas 中四舍五入?
确定一天是不是是 Python / Pandas 中的工作日