【问题标题】:How do I assign elements to the column of a pandas dataframe based on the properties of groups derived from that dataframe?如何根据从该数据框派生的组的属性将元素分配给熊猫数据框的列?
【发布时间】:2019-10-19 02:43:32
【问题描述】:

假设我按如下方式导入 pandas 和 numpy:

import pandas as pd
import numpy as np

并构造以下数据框:

df = pd.DataFrame({'Alpha' 
['A','A','A','B','B','B','B','C','C','C','C','C'],'Beta' : np.NaN})

...这给了我这个:

    Alpha  Beta
0      A   NaN
1      A   NaN
2      A   NaN
3      B   NaN
4      B   NaN
5      B   NaN
6      B   NaN
7      C   NaN
8      C   NaN
9      C   NaN
10     C   NaN
11     C   NaN

如何使用 pandas 获取以下数据框?

df_u = pd.DataFrame({'Alpha':['A','A','A','B','B','B','B','C','C','C','C','C'],'Beta' : [1,2,3,1,2,2,3,1,2,2,2,3]})

即这个:

   Alpha  Beta
0      A     1
1      A     2
2      A     3
3      B     1
4      B     2
5      B     2
6      B     3
7      C     1
8      C     2
9      C     2
10     C     2
11     C     3

一般来说,我想要达到的目标可以用以下逻辑来描述:

假设我们将 df 按 Alpha 分组。

对于每个组,对于组中的每一行...

  • 如果行的索引等于组中行的最小索引,则将该行的 Beta 赋值为 1,

  • 如果行的索引等于组中行的最大索引,则将该行的 Beta 赋值为 3,

  • 否则将 2 分配给该行的 Beta。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    让我们使用重复:

    df.loc[~df.duplicated('Alpha', keep='last'), 'Beta'] = 3
    df.loc[~df.duplicated('Alpha', keep='first'), 'Beta'] = 1
    df['Beta'] = df['Beta'].fillna(2)
    print(df)
    

    输出:

       Alpha  Beta
    0      A   1.0
    1      A   2.0
    2      A   3.0
    3      B   1.0
    4      B   2.0
    5      B   2.0
    6      B   3.0
    7      C   1.0
    8      C   2.0
    9      C   2.0
    10     C   2.0
    11     C   3.0
    

    【讨论】:

      【解决方案2】:

      方法一

      使用np.select:

      mask1=df['Alpha'].ne(df['Alpha'].shift())
      mask3=df['Alpha'].ne(df['Alpha'].shift(-1))
      mask2=~(mask1|mask3)
      cond=[mask1,mask2,mask3]
      values=[1,2,3]
      df['Beta']=np.select(cond,values)
      print(df)
      

         Alpha  Beta
      0      A     1
      1      A     2
      2      A     3
      3      B     1
      4      B     2
      5      B     2
      6      B     3
      7      C     1
      8      C     2
      9      C     2
      10     C     2
      11     C     3
      

      条件列表详情:

      print(mask1)
      0      True
      1     False
      2     False
      3      True
      4     False
      5     False
      6     False
      7      True
      8     False
      9     False
      10    False
      11    False
      Name: Alpha, dtype: bool
      

      print(mask2)
      0     False
      1      True
      2     False
      3     False
      4      True
      5      True
      6     False
      7     False
      8      True
      9      True
      10     True
      11    False
      Name: Alpha, dtype: bool
      

      print(mask3)
      0     False
      1     False
      2      True
      3     False
      4     False
      5     False
      6      True
      7     False
      8     False
      9     False
      10    False
      11     True
      Name: Alpha, dtype: bool
      

      方法2

      使用groupby:

      def assign_value(x):
          return pd.Series([1]+[2]*(len(x)-2)+[3])
      new_df=df.groupby('Alpha').apply(assign_value).rename('Beta').reset_index('Alpha') 
      print(new_df)
      

        Alpha  Beta
      0     A     1
      1     A     2
      2     A     3
      0     B     1
      1     B     2
      2     B     2
      3     B     3
      0     C     1
      1     C     2
      2     C     2
      3     C     2
      4     C     3
      

      【讨论】:

        【解决方案3】:

        假设“Alpha”列已排序,您可以这样做

        df["Beta"] = 2
        df.loc[~(df["Alpha"] == df["Alpha"].shift()), "Beta"] = 1
        df.loc[~(df["Alpha"] == df["Alpha"].shift(-1)), "Beta"] = 3
        df
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-02-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-05-21
          • 2022-01-25
          • 2022-06-27
          • 2022-01-12
          相关资源
          最近更新 更多