Pandas:合并两个具有重复行的数据框

Rob*_*ley 3 python csv pandas

简短问题 在 Pandas 中,合并两个数据帧的最方便的方法是什么,以便左侧数据帧中的所有条目都接收来自右侧数据帧的第一个匹配值?

更长的问题 假设我有两个电子表格:people.csvorders.csv. people.csv包含有关此人的多列信息,而orders.csv包含此人的全名,以及该人所下订单数量的一行。

我需要创建第三个 csv,output.csv其中包含来自的所有列people.csv以及output.csv与两个电子表格中的一列匹配的列(一个称为“FULL_NAME”,另一个称为“CUSTOMER_FULL_NAME”)

people.csv在 FULL_NAME 字段上排序,但包含重复的行,因此在 FULL_NAME 列中有多个带有“John Smith”的行。也有重复的行,orders.csv但重复的数量不同(例如,people.csv可能有 4 个 John Smith 条目,但orders.csv可能只有两个)。

如果我使用以下代码:

people = pd.read_csv('people.csv')
orders = pd.read_csv('orders.csv')
full = pd.merge(
    people,
    orders,
    left_on='FULL_NAME',
    right_on='CUSTOMER_FULL_NAME',
)
result.to_csv("output.csv")
Run Code Online (Sandbox Code Playgroud)

...我得到一个 CSV,其中只有 FULL_NAME 字段中带有“John Smith”的两行包含 John Smith 的订单数。正下方的行在该字段中没有值。那是因为output.csv只包含两行与 John Smith 匹配的值,而people.csv有 4 行。

Pandas 中是否有一种方便的方法可以将一列的值设置为另一个数据框中的第一个匹配列,以便所有 4 个条目都包含来自 的第一个匹配值orders.csv

编辑 我的脚本的完整当前版本,返回包含未使用预期值设置的行的 CSV:

import pandas as pd

community = pd.read_csv("orders.csv")
full = pd.read_csv("people.csv")
result = pd.merge(
    full,
    community.drop_duplicates(subset=['FULL_NAME'], keep='first'),
    left_on="CUSTOMER_FULL_NAME",
    right_on="FULL_NAME",
    how='left',
)
result.to_csv("output.csv")
Run Code Online (Sandbox Code Playgroud)

所以我想我在这里遗漏了其他东西,因为某些行以预期的方式匹配。这是输出文件中的一个示例:

ID      FULL_NAME   EMPLOYER            DIVISION            ORDER #
7350    John Smith  RiteAid             Clinical Research   25
7351    John Smith  RiteAid             Clinical Research   25
7352    John Smith  Costco              Sales   
7353    John Smith  Costco              Sales   
Run Code Online (Sandbox Code Playgroud)

这个 John Smith 行在文件中没有重复的值,orders.csv所以我认为这是有效的,因为有两行得到了它。但是,我没有在列出 Costco 而不是 RiteAid(或其他不同字段)的 John Smith 行上找到匹配项。这让我感到惊讶,因为我认为索引检查只针对 FULL_NAME 字段。

关于为什么其他行可能不会被填充的任何想法?

Ben*_*n.T 5

您可以在with 中使用drop_duplicateson来保留所有行,例如:subset=['CUSTOMER_FULL_NAME']mergehow='left'people

full = pd.merge(
    people,
    orders.drop_duplicates(subset=['CUSTOMER_FULL_NAME'], keep='first'), #here the differance
    left_on='FULL_NAME',
    right_on='CUSTOMER_FULL_NAME',
    how='left' #and add the how='left'
)
Run Code Online (Sandbox Code Playgroud)

因此orders.drop_duplicates(subset=['CUSTOMER_FULL_NAME'], keep='first'),每个名称只包含一次,并且在 期间merge,匹配将仅具有此唯一名称