使用熊猫聚合多列定性数据?

时间:2021-01-22 00:40:33

标签: python r pandas group-by tidyr

我想从这里开始:

<头>
姓名 宠物
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")))

我将如何使用熊猫来做到这一点?

2 个答案:

答案 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