我有以下排序的数据框,其在文本文件中具有特定行的位置
数据:
index position
0 125
1 256
2 314
3 355
4 549
5 601
6 654
7 727
8 1100
9 1217
我有另一个数据框,其中包含消息msg1,msg2和msg3以及它们在文本文件中的位置,并且可以具有多个实例。这些消息表示如何对数据进行分组
消息:
index position message
0 210 msg1
1 313 msg2
2 525 msg3
3 575 msg2
4 632 msg1
5 731 msg3
条件
a)如果该行位于第一次遇到的消息之前(不一定是msg1,则由位置标识),则该行将被分类为A级。
b)如果该行在最后一条消息之后(不一定是msg3,则由位置标识),则该行将被分类为:
a) if msg1 is last: grade A1
b) if msg2 is last: grade A2
c) if msg3 is last: grade A3
c)如果该行位于两条消息之间,即msg [i]的开始和msg [j]的结束,则该行将被分类为“ A级+ str(i)”
我尝试了if else语句,但未能正确实现它。在不对消息帧中的位置进行任何硬编码的情况下,采用任何更简单的方式进行操作将受到赞赏。
预期输出是熊猫系列/数据框或根据条件分组的行列表
index position group
0 125 grade A
1 256 grade A1
2 314 grade A2
3 355 grade A2
4 549 grade A3
5 601 grade A2
6 654 grade A1
7 727 grade A1
8 1100 grade A3
9 1217 grade A3
答案 0 :(得分:0)
对于消息数据框中的每一行,我们添加下一条消息的位置,以方便比较:
messages = messages.join(messages['position'].shift(-1).rename('next_position'))
为数据中的每一行添加消息:
data['class'] = 0
for index, row in messages.iterrows():
data.loc[data['position'].between(row['position'],row['next_position']),'class'] = row['message']
添加“边缘”情况:
data.loc[data['position'].between(0,messages['position'].min()),'class'] = 'msg'
data.loc[data['position'].between(messages['position'].max(),np.inf),'class'] = messages.iloc[-1]['message']
然后用您的班级替换消息
for message_code in data['class'].unique():
data.replace(message_code,'A'+message_code.split('msg')[-1],inplace=True)
答案 1 :(得分:0)
我会
grade
+消息编号的消息的行添加新列'grade A'
position
列上对连接的数据框进行排序fillna
用上一封邮件的等级填充等级列fillna
将第一条消息之前的任何行设置为'grade A'
代码可能是:
tmp = pd.concat([df1,df2], sort=False).sort_values(
['position'])
tmp.loc[~tmp['message'].isna(),'grade'] = 'grade A' + tmp.loc[
~tmp['message'].isna(),'message'].str[3]
tmp['grade']=tmp['grade'].fillna(method='ffill').fillna('grade A')
resul = tmp.loc[tmp.message.isna()].drop(columns=['message'])
使用您的示例数据,它可以提供预期的结果:
index position grade
0 125 grade A
1 256 grade A1
2 314 grade A2
3 355 grade A2
4 549 grade A3
5 601 grade A2
6 654 grade A1
7 727 grade A1
8 1100 grade A3
9 1217 grade A3