我有这样的DataFrame
:
message_id reply_to_id sender
0 1 0 Roozbeh
1 2 1 Amir
2 3 0 Neda
3 4 2 Roozbeh
3 5 2 Neda
如果该消息是对另一条消息的答复,则reply_to_id
会显示已回复的消息的ID,否则为0
。现在,我想创建另一列reply_to_sender
,在其中显示已回复邮件的发件人的名称(如果不是答复,则可以显示NaN
)< / p>
message_id
列是唯一的,但是reply_to_id
和sender
列显然不是。
我尝试过:
data["reply_to_sender"] = data.loc[data["reply_to_id"] == data["message_id"]]["sender"]
但是它显然行不通,因为它会查看每一行并执行关系操作。我想做的是查看每一行,然后从其他行中找到发件人的名字。对于上面的示例,输出需要像这样:
message_id reply_to_id sender reply_to_sender
0 1 0 Roozbeh NaN
1 2 1 Amir Roozbeh
2 3 0 Neda NaN
3 4 2 Roozbeh Amir
3 5 2 Neda Amir
我该怎么做?
答案 0 :(得分:5)
将Series.map
与Series
和message_id
创建的sender
一起使用:
df['reply_to_sender'] = df['reply_to_id'].map(df.set_index('message_id')['sender'])
print (df)
message_id reply_to_id sender reply_to_sender
0 1 0 Roozbeh NaN
1 2 1 Amir Roozbeh
2 3 0 Neda NaN
3 4 2 Roozbeh Amir
3 5 2 Neda Amir
答案 1 :(得分:0)
首先,让我们看看您将如何手动完成此操作。然后我们用代码实现它。
如果我给您一个reply_to_id
,只需查看DataFrame
,找到message_id
等于该行的行,就可以告诉我此消息是谁的回复数字,然后告诉我该行的sender
列中的值。可以这样完成,其中reply_to_id
变量是我给您的数字:
data.loc[data["message_id"] == reply_to_id]["sender"]
现在此代码返回一个pandas.Series,但我们没有要求一个Series
,而是要求了一个标量值,它是发送者的名字。因此,我们需要从系列中提取该值。如果系列中只有一个值(您需要检查),我们可以使用pandas.Series.values[0]
提取它。所以代码变成这样:
reply_to_sender_values = data.loc[data["message_id"] == reply_to_id]["sender"].values
if len(reply_to_sender_values) == 1:
return reply_to_sender_values[0]
现在,如果我给您一个您在message_id
中找不到的电话号码会怎样?你会怎么做?您会告诉我您什么都没找到。就是这样:
reply_to_sender_values = data.loc[data["message_id"] == reply_to_id]["sender"].values
if len(reply_to_sender_values) == 1:
return reply_to_sender_values[0]
else:
return ""
我们还需要注意一件事。如您所说,reply_to_id
中的值可以为零。因此,我们需要注意以下事项:
if(reply_to_id != 0):
reply_to_sender_values = data.loc[data["message_id"] == reply_to_id]["sender"].values
if len(reply_to_sender_values) == 1:
return reply_to_sender_values[0]
else:
return ""
else:
return ""
如您所见,我们刚刚构建了一个函数来手动执行操作。我们给它起个名字:
def reply_to_sender(reply_to_id):
if(reply_to_id != 0):
reply_to_sender_values = data.loc[data["message_id"] == reply_to_id]["sender"].values
if len(reply_to_sender_values) == 1:
return reply_to_sender_values[0]
else:
return ""
else:
return ""
剩下要做的就是找到一种方法,在我们reply_to_id
的{{1}}列的所有行上应用。幸运的是,DataFrame
中有一个方法可以做到这一点。您猜对了,它叫做pandas.DataFrame.apply
。现在,所有这些都与以下代码行一起出现:
Pandas
值得注意的是,我在 Jupyter Notebook中测试了此代码。如果要从脚本运行此代码,则需要将data["reply_to_sender"] = data["reply_to_id"].apply(lambda x: reply_to_sender(x))
传递给{{1 }}函数。因此代码更改为:
DataFrame
答案 2 :(得分:0)
你可以做
mymap = {val: df.sender.loc[key] for key, val in df.message_id.to_dict().items()}
然后
df['reply_to_sender'] = df.reply_to_id.map(mymap)
这给你
message_id reply_to_id sender reply_to_sender
0 1 0 Roozbeh NaN
1 2 1 Amir Roozbeh
2 3 0 Neda NaN
3 4 2 Roozbeh Amir
3 5 2 Neda Amir