在Python中有条件地从具有不同大小的数据框创建列

时间:2020-07-17 11:20:58

标签: python pandas dataframe

我有如下数据框:

df = pd.DataFrame({'buck' : ['3', '3', '3', '2', '2', '1', '1', '1', '0', '0'], 
                   'rank' : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]})
df2 = pd.DataFrame({'col_no' : ['mr.A', 'mr.B', 'mr.C', 'mr.D', 'mr.E', 'mr.F', 'mr.G'],
                    'grade' : ['H', 'H', 'M', 'M', 'L', 'L', 'L']})

我想基于'col_no'df2的条件,使用df中的df2在df中创建一列。 条件如下:

  1. df['buck'] == 3 and df2['grade'] == 'H'
  2. df['buck'] == 2 and df2['grade'] == 'M'
  3. (df['buck'] == 1 or df['buck'] == 0) and df2['grade'] == 'L'

如果满足条件->>遍历df2['col_no']并重复输入相应的值。

例如,条件1的唯一值是mr.A和mr.B。

所需的输出将是:

buck     rank     col_no        
3        1        mr.A        
3        2        mr.B       
3        3        mr.A
2        4        mr.C
2        5        mr.D
1        6        mr.E        
1        7        mr.F     
1        8        mr.G        
0        9        mr.E
0        10       mr.F

我是Python的新手,不知道解决这个问题的关键词是什么。我唯一想到的选择是编写一个硬代码遍历每一行,而不使用Panda编码样式。

因此,任何建议将不胜感激。 在此先感谢!

1 个答案:

答案 0 :(得分:1)

我会使用映射和转换函数

grades = {'3': 'H', '2': 'M', '1': 'L', '0': 'L'}

def trans(x):
    ln = len(x)
    grade = grades[x.name]         # find the corresponding grade
    data = df2[df2['grade'] == grade, 'col_no'].to_list() # extract matching data from df2
    data *= (ln // len(data)) + 1  # repeat as required
    return data[:ln]               # and return the expected len

然后就这么简单:

df.assign(col_no=df.groupby('buck')['buck'].transform(trans))

它给出了预期的结果:

  buck  rank col_no
0    3     1   mr.A
1    3     2   mr.B
2    3     3   mr.A
3    2     4   mr.C
4    2     5   mr.D
5    1     6   mr.E
6    1     7   mr.F
7    1     8   mr.G
8    0     9   mr.E
9    0    10   mr.F

上面的代码从GroupBy对象请求一个单独的列,从transform调用的函数每次接收一个单独的Series,其中名称是组标识符(这里是{{ 1}}到'0'),并将这些值设为该列中的相应值。