繁体   English   中英

python pandas在组内排序并应用函数

[英]python pandas sort within group and apply function

假设我有虹膜数据集。 有没有办法在熊猫中简洁地执行以下操作?

  1. 按目标分组
  2. 每组内,按“萼片长度(cm)”降序排列数据
  3. 在每个组中,将 1 分配给前 5 行,将 0 分配给其余行?

对于那些了解 R 的人,我只想复制以下代码(是的,这是一种解决方法):

iris %>%
  group_by(Species) %>%
  arrange(desc(Sepal.Length)) %>%
  mutate(size_tag = 1,
         size_tag = cumsum(size_tag),
         size_tag = ifelse(size_tag <= 5, 1, 0))

到目前为止,我有:

from sklearn import datasets
iris = datasets.load_iris()
iris = pd.DataFrame(data= np.c_[iris['data'], iris['target']],
                 columns= iris['feature_names'] + ['target'])

def fn(group, col_nm):
    group[col_nm] = 1
    group[col_nm] = np.cumsum(group[col_nm])
    group[col_nm] = np.where(group[col_nm] <= 5, 1, 0)
return group

iris['size_tag'] = np.NaN
iris.groupby('target').apply( pd.DataFrame.sort_values, 'sepal length (cm)' ).apply( fn, args = (['size_tag']))

我得到的结果是附加到 DataFrame 的额外行...

我刚刚开始使用 Pandas 和 Python,因此欢迎提出任何意见(例如与编码风格相关的)。

这得到一系列的 1 和 0

iris.sort_values(
    'sepal length (cm)', ascending=False
).groupby('target').cumcount().__floordiv__(5).eq(0).astype(np.uint8)

更具可读性

s = iris.sort_values('sepal length (cm)', ascending=False)
c = s.groupby('target').cumcount()
((c // 5) == 0).astype(np.uint8)

使用新列生成副本

s = iris.sort_values('sepal length (cm)', ascending=False)
c = s.groupby('target').cumcount()
top5 = ((c // 5) == 0).astype(np.uint8)
iris.assign(size_tag=top5)

在此处输入图片说明

我复制了你的 R 数据框,我认为这做了同样的事情:

iris = iris.sort_values(['target', 'sepal length (cm)'], ascending=False)
iris['size_tag'] = iris.index.isin(iris.groupby('target').head(5).index)*1

我们首先按物种对值进行排序,然后按每个物种组内的萼片长度排序。 然后我们为每个组添加前 5 个标签。

R ,您不需要cumsum()来计算行号。 row_number()函数为您完成:

r$> iris %>% 
      group_by(Species) %>% 
      arrange(desc(Sepal.Length)) %>% 
      mutate(size_tag = if_else(row_number() <= 5, 1, 0))  
# A tibble: 150 x 6
# Groups:   Species [3]
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species   size_tag
          <dbl>       <dbl>        <dbl>       <dbl> <fct>        <dbl>
 1          7.9         3.8          6.4         2   virginica        1
 2          7.7         3.8          6.7         2.2 virginica        1
 3          7.7         2.6          6.9         2.3 virginica        1
 4          7.7         2.8          6.7         2   virginica        1
 5          7.7         3            6.1         2.3 virginica        1
 6          7.6         3            6.6         2.1 virginica        0
 7          7.4         2.8          6.1         1.9 virginica        0
 8          7.3         2.9          6.3         1.8 virginica        0
 9          7.2         3.6          6.1         2.5 virginica        0
10          7.2         3.2          6           1.8 virginica        0
# … with 140 more rows

现在我们有能力在 python 中使用datar以相同的方式做到这datar

>>> from datar.all import f, group_by, arrange, desc, mutate, row_number, if_else
>>> from datar.datasets import iris
>>> 
>>> iris >> \
...   group_by(f.Species) >> \
...   arrange(desc(f.Sepal_Length)) >> \
...   mutate(size_tag = if_else(row_number() <= 5, 1, 0))
     Sepal_Length  Sepal_Width  Petal_Length  Petal_Width    Species  size_tag
        <float64>    <float64>     <float64>    <float64>   <object>   <int64>
0             7.9          3.8           6.4          2.0  virginica         1
1             7.7          2.8           6.7          2.0  virginica         1
2             7.7          3.8           6.7          2.2  virginica         1
3             7.7          2.6           6.9          2.3  virginica         1
..            ...          ...           ...          ...        ...       ...
4             7.7          3.0           6.1          2.3  virginica         1
145           4.5          2.3           1.3          0.3     setosa         0
146           4.4          2.9           1.4          0.2     setosa         0
147           4.4          3.0           1.3          0.2     setosa         0
148           4.4          3.2           1.3          0.2     setosa         0
149           4.3          3.0           1.1          0.1     setosa         0

[Groups: Species (n=3)]
[150 rows x 6 columns]

我是datar包的作者。 如果您有任何问题,请随时提交问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM