我有如下数据框:
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中创建一列。
条件如下:
df['buck'] == 3 and df2['grade'] == 'H'
df['buck'] == 2 and df2['grade'] == 'M'
(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编码样式。
因此,任何建议将不胜感激。 在此先感谢!
答案 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'
),并将这些值设为该列中的相应值。