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

时间:2017-01-17 17:29:35

标签: python r pandas apply

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

  1. 按目标分组
  2. 在每个组中,按“sepal length(cm)”
  3. 按降序排列数据
  4. 在每个组中,为前5行分配1,为其余分配0?
  5. 对于那些了解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,所以欢迎任何评论(例如与编码风格相关)。

3 个答案:

答案 0 :(得分:2)

这会得到一系列的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)

enter image description here

答案 1 :(得分:1)

我复制了你的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位添加标签。

答案 2 :(得分:0)

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 以同样的方式做到这一点:

>>> 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 包的作者。如果您有任何问题,请随时提交问题。