是否有一种pythonic方式在熊猫中做一个列联表?

her*_*lla 24 python dataframe python-2.7 pandas

给定一个如下所示的数据框:

            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  
Run Code Online (Sandbox Code Playgroud)

是否有pythonic方法来创建像这样的2x2矩阵:

    1  0
 1  a  b
 0  c  d
Run Code Online (Sandbox Code Playgroud)

哪里:

a =列数A和B的相应元素均为正数.

b =列A的相应元素在B列中为正和负的obs数.

c =列A中相应元素为负且在B列中为正的obs数.

d =列数A和B的相应元素均为负数的obs数.

对于此示例,输出将是:

    1  0
 1  2  3
 0  3  1
Run Code Online (Sandbox Code Playgroud)

谢谢

Tyr*_*nks 29

可能最容易使用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)
Run Code Online (Sandbox Code Playgroud)

输出:

B      False  True 
A                  
False      1      3
True       3      2

[2 rows x 2 columns]
Run Code Online (Sandbox Code Playgroud)

如果您想使用scipy.stats等等进行Fisher精确测试,该表也可用:

from scipy.stats import fisher_exact
tab = pd.crosstab(df.A > 0, df.B > 0)
fisher_exact(tab)
Run Code Online (Sandbox Code Playgroud)


lan*_*nok 17

我们来调用您的数据帧data.尝试

a = data['A']>0
b = data['B']>0
data.groupby([a,b]).count() 
Run Code Online (Sandbox Code Playgroud)

  • 无论是谁投了这个答案:请发表评论 - 为什么. (2认同)

Jos*_*ing 8

这是一个关于pandas交叉表功能的非常有用的页面:

http://chrisalbon.com/python/pandas_crosstabs.html

所以我认为你应该使用你想做的事情

import pandas as pd
pd.crosstab(data['A']>0, data['B']>0)
Run Code Online (Sandbox Code Playgroud)

希望有所帮助!


Dyn*_* Fu 5

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()
Run Code Online (Sandbox Code Playgroud)

输出:

B      False  True
A
False      1      3
True       3      2
Run Code Online (Sandbox Code Playgroud)

这只是lnanenok的答案,并unstack()用来使其更具可读性。应归功于Lanenok。