熊猫 - 给定特定b的条件概率

Ham*_*d K 5 python pandas

我有两列"a"和"b"的DataFrame.如何找到给定特定"b"的"a"的条件概率?

df.groupby('a').groupby('b')
Run Code Online (Sandbox Code Playgroud)

不起作用.让我们假设我在列a中有3个类别,对于每个特定的我有5个类别的b.我需要做的是找出每个类的一个b类的总数.我试过应用命令,但我想我不知道如何正确使用它.

df.groupby('a').apply(lambda x: x[x['b']] == '...').count()
Run Code Online (Sandbox Code Playgroud)

max*_*moo 12

要查找您将要执行的b每个类实例的类总数a

df.groupby('a').b.value_counts()
Run Code Online (Sandbox Code Playgroud)

例如,创建一个DataFrame,如下所示:

df = pd.DataFrame({'A':['foo', 'bar', 'foo', 'bar','foo', 'bar', 'foo', 'foo'], 'B':['one', 'one', 'two', 'three','two', 'two', 'one', 'three'], 'C':np.random.randn(8), 'D':np.random.randn(8)})

     A      B         C         D
0  foo    one -1.565185 -0.465763
1  bar    one  2.499516 -0.941229
2  foo    two -0.091160  0.689009
3  bar  three  1.358780 -0.062026
4  foo    two -0.800881 -0.341930
5  bar    two -0.236498  0.198686
6  foo    one -0.590498  0.281307
7  foo  three -1.423079  0.424715
Run Code Online (Sandbox Code Playgroud)

然后:

df.groupby( 'A')[ 'B'].value_counts()

df.groupby('A')['B'].value_counts()

A
bar  one      1
     two      1
     three    1
foo  one      2
     two      2
     three    1
Run Code Online (Sandbox Code Playgroud)

要将此转换为条件概率,您需要除以每个组的总大小.

您可以使用其他组来执行此操作:

df.groupby('A')['B'].value_counts() / df.groupby('A')['B'].count()

A
bar  one      0.333333
     two      0.333333
     three    0.333333
foo  one      0.400000
     two      0.400000
     three    0.200000
dtype: float64
Run Code Online (Sandbox Code Playgroud)

或者您可以将lambda功能应用于组:

df.groupby('a').b.apply(lambda g: g.value_counts()/len(g))
Run Code Online (Sandbox Code Playgroud)


小智 5

回答:

这可以使用 Pandas 交叉表函数来完成。鉴于 Dataframe 被称为“df”的问题的描述,列“a”和“b”

pd.crosstab(df.a, df.b, normalize='columns')

将返回一个 Dataframe 表示 P(a | b)

https://pandas.pydata.org/pandas-docs/version/0.23.4/generated/pandas.crosstab.html

解释:

考虑数据帧:

df = pd.DataFrame({'a':['x', 'x', 'x', 'y', 'y', 'y', 'y', 'z'],
                   'b':['1', '2', '3', '4','5', '1', '2', '3']})
Run Code Online (Sandbox Code Playgroud)

查看列 a 和 b

df[["a", "b"]]

我们有

    a   b
0   x   1
1   x   2
2   x   3
3   y   4
4   y   5
5   y   1
6   y   2
7   z   3
Run Code Online (Sandbox Code Playgroud)

然后

pd.crosstab(df.a, df.b)

返回 df.a 和 df.b 的频率表,其中行是 df.a 的值,列是 df.b 的值

b   1   2   3   4   5
a                   
x   1   1   1   0   0
y   1   1   0   1   1
z   0   0   1   0   0
Run Code Online (Sandbox Code Playgroud)

我们可以改为使用 normalize 关键字来获取条件概率表 P(a | b)

pd.crosstab(df.a, df.b, normalize='columns')

这将根据列值进行标准化,或者在我们的情况下,返回一个 DataFrame,其中列表示P(a | b=B)B 的特定值的条件概率

b    1   2   3   4   5
a
x   0.5 0.5 0.5 0.0 0.0
y   0.5 0.5 0.0 1.0 1.0
z   0.0 0.0 0.5 0.0 0.0
Run Code Online (Sandbox Code Playgroud)

请注意,列总和为 1。

如果我们更喜欢 get P(b | a),我们可以对行进行标准化

pd.crosstab(df.a, df.b, normalize='rows')

要得到

b      1           2           3         4       5
a                   
x   0.333333    0.333333    0.333333    0.00    0.00
y   0.250000    0.250000    0.000000    0.25    0.25
z   0.000000    0.000000    1.000000    0.00    0.00
Run Code Online (Sandbox Code Playgroud)

其中行表示P(b | a=A)A 的特定值的条件概率。请注意,行总和为 1。