我想从这里开始:
姓名 | 宠物 | |
---|---|---|
1 | 拉希达 | 狗 |
2 | 拉希达 | 猫 |
3 | 吉姆 | 狗 |
4 | 吉姆 | 狗 |
为此:
姓名 | num_dogs | num_cats | |
---|---|---|---|
1 | 吉姆 | 2 | 0 |
2 | 拉希达 | 1 | 1 |
在 R 我会做
df %>%
group_by(name) %>%
summarize(num_dogs = length(which(pet == "dog")),
num_cats = length(which(pet == "cat")))
我将如何使用熊猫来做到这一点?
答案 0 :(得分:1)
有很多不同的方法可以做到这一点。
如果您要过滤单个列的值,则可以将 .agg 与自定义 lambda 函数一起使用。
(df.groupby(["name"])
.agg(
num_dogs=("pet", lambda x: np.sum(x == "dog")),
num_cats=("pet", lambda x: np.sum(x == "cat")))
)
或
(df
.groupby(["name", "pet"])
.size()
.unstack("pet", fill_value=0)
.add_prefix("num_").add_suffix("s")
)
您也可以使用数据透视表。
df.reset_index().pivot_table(index="name", columns="pet", values="index", aggfunc="count", fill_value=0)
但是如果您需要基于两列进行过滤,那么这种方法将不起作用。例如,如果您需要知道有多少只老狗。
df = pd.DataFrame({'name': ["Rashida", "Rashida", "Joe", "Joe"],
'pet': ['dog', 'cat', 'dog', 'dog'],
'age': ["old", "old", "old", "young"]})
您可以使用数据透视表。
df.reset_index().pivot_table(index="name", columns=["pet", "age"], values="index", aggfunc="count", fill_value=0)
或交叉表。
pd.crosstab(df["name"], [df["pet"], df["age"]], dropna=False).unstack().reset_index()
或者你可以使用名为 siuba 的 Dplyr 端口来模仿原始的 R 语法,但我还没有使用过它,不知道如何使用它。
from siuba import group_by, summarize, _
答案 1 :(得分:1)
您可以使用由 Pandas 提供支持的 datar
:
>>> from datar.all import f, tribble, length, group_by, which, summarise
>>>
>>> df = tribble(
... f.name, f.pet,
... "Rashida", "dog",
... "Rashida", "cat",
... "Jim", "dog",
... "Jim", "dog",
... )
>>>
>>> df >> group_by(f.name) >> summarise(
... num_dogs = length(which(f.pet == "dog")),
... num_cats = length(which(f.pet == "cat"))
... )
name num_dogs num_cats
<object> <int64> <int64>
0 Jim 2 0
1 Rashida 1 1