我有一个像这样的DataFrame data
:
Observation A_1 A_2 A_3 B_1 B_2 B_3
Obs1 yes no yes no no no
Obs2 no no no yes yes yes
Obs3 yes yes yes yes yes yes
目标:计算标记为“是”的所有观察的频率:
编辑:这意味着我需要排除前两个计数中包含“是”的观察结果 A和B组(见第三行)。
我考虑过使用groupby
:
grouper = data.groupby(lambda x: x.split("_")[0], axis=1)
grouped = grouper.agg(lambda x: sum(x == "yes"))
但我的计数除以行,这不是我想要的。
这里最好的行动是什么?
编辑:根据要求,提供有关输出的更多信息。我喜欢像
这样的东西Frequency of valid [meaning "yes"] observations in group A: X
Frequency of valid observations in group "B": Y
Frequency for all valid observations: Z
其中X,Y和Z是返回的计数。
我不关心个别观察的特定输出。我对所有这些人的价值观感兴趣。
答案 0 :(得分:3)
In [129]: a = ['A_1', 'A_2', 'A_3']
In [130]: b = ['B_1', 'B_2', 'B_3']
In [131]: ina = (df[a] == 'yes').any(axis=1)
In [132]: inb = (df[b] == 'yes').any(axis=1)
In [133]: ina & ~inb
Out[133]:
Observation
Obs1 True
Obs2 False
Obs3 False
dtype: bool
In [134]: ~ina & inb
Out[134]:
Observation
Obs1 False
Obs2 True
Obs3 False
dtype: bool
In [135]: ina & inb
Out[135]:
Observation
Obs1 False
Obs2 False
Obs3 True
dtype: bool
可以使用value_counts进行计数:(ina& inb).value_counts()[True]
答案 1 :(得分:2)
我还不清楚你是否希望yes no yes no no no
算作1或2.我最需要的东西看起来像这样:
>>> df
A_1 A_2 A_3 B_1 B_2 B_3
Observation
Obs1 yes no yes no no no
Obs2 no no no yes yes yes
Obs3 yes yes yes yes yes yes
Obs4 yes yes no no no no
>>> y = (df == "yes").groupby(lambda x: x.split("_")[0], axis=1).sum()
>>> y
A B
Observation
Obs1 2 0
Obs2 0 3
Obs3 3 3
Obs4 2 0
>>> which = y.apply(lambda x: tuple(x.index[x > 0]), axis=1)
>>> which
Observation
Obs1 (A,)
Obs2 (B,)
Obs3 (A, B)
Obs4 (A,)
dtype: object
>>> y.groupby(which).sum()
A B
(A,) 4 0
(A, B) 3 3
(B,) 0 3
或者可能只是
>>> which.value_counts()
(A,) 2
(A, B) 1
(B,) 1
dtype: int64
取决于你的目标。