pandas 创建一个单条目字典列表,其中每个给定列的分组为除第1行(关键行)以外的所有行贡献第2列的值

3phpmpom  于 2023-03-11  发布在  其他
关注(0)|答案(1)|浏览(106)

我有一个Pandas的数据框,看起来像这样:
| 标头1|标题2|
| - ------|- ------|
| 第一次|行1|
| 第二次|行2|
| 第三次|行1|
| 第四次|行2|
| 第五次|行1|
我想创建一个字典列表,其中,对于在header 2列中具有匹配值的所有行(除了第一行),使用第一行的header 1列值作为londict键,每隔一行的header 1列值作为londict值,将字典添加到列表中。
预期产出:
[{“第一次”:“第三次},{“第二次”:“第四次”},{“第一次”:“第五次”}]
甚至
{“First”:“Third”,“Second”:“Fourth”}(此输出不处理标题2中的多个匹配项)
理想情况下,解决方案不会是计算密集型的,因为我已经能够用嵌套的for循环完成这一点。
根据评论中提出的内容进行编辑:如果第一列中有多个值与header 2匹配,则假定第一个出现的值将是关键字,并与值重复。例如:[{“First”:“Third},{“Second”:“Fourth”},{“First”:“Fifth”}]。换句话说,第一个匹配行中的header 1值将是重复关键字,并为每个后续匹配行的结果列表添加一个单条目字典。
谢谢

wvyml7n5

wvyml7n51#

下面是一个解决问题的方法:

out = []
df.groupby('header2')['header1'].apply(lambda x: out.extend([{x.iloc[0]:x.iloc[i]} for i in range(1, len(x))]) if len(x) > 1 else None)
idxByHeader1 = df.reset_index(drop=False).set_index('header1')['index']
out = sorted(out, key=lambda x: idxByHeader1[list(x.values())[0]])

输出:

[{'First': 'Third'}, {'Second': 'Fourth'}, {'First': 'Fifth'}]

更新日期:

下面是一个稍微可靠的答案,假设header1列中的值可以在不同的header2值之间复制,这个更新的答案将确保结果列表中的字典保持原始 Dataframe 中的顺序。

out = []
df.assign(dup=df.apply(tuple, axis=1)).groupby('header2')['dup'].apply(
    lambda x: out.extend([{x.iloc[0][0]:x.iloc[i]} 
    for i in range(1, len(x))]) if len(x) > 1 else None)
idx = df.reset_index(drop=False).set_index(['header1','header2'])['index']
out = sorted(out, key=lambda x: idx[list(x.values())[0]])
out = [{key:val[0]} for item in out for key, val in item.items()]
print(out)

样本输入:(注意Fifth的复制,对于键Second,再次对于键First):

header1 header2
0   First    row1
1  Second    row2
2   Third    row1
3   Fifth    row2
4   Fifth    row1

输出:(注意,对于以Fifth作为值的两个字典,以Second作为键的字典出现在以First作为键的字典 * 之前 *,这与原始 Dataframe 中的排序相同,因为遇到的第一个Fifth具有与Second匹配的header2值):

[{'First': 'Third'}, {'Second': 'Fifth'}, {'First': 'Fifth'}]

相关问题