Python 基于并行列中的匹配值对数据帧行进行排序

Python 基于并行列中的匹配值对数据帧行进行排序,python,python-3.x,pandas,Python,Python 3.x,Pandas,编辑:根据要求,这里是两个数据帧在我对其进行分析之前的样子,并且由于它们具有相同的列类型,因此其字面意思是: # The Larger dataset, there are 4 other columns after, which the smaller dataframe shares in type id Port 123ABC Boston Port # The smaller dataset id Port 45

编辑:根据要求,这里是两个数据帧在我对其进行分析之前的样子,并且由于它们具有相同的列类型,因此其字面意思是:

# The Larger dataset, there are 4 other columns after, which the smaller dataframe shares in type

      id      Port  
    123ABC  Boston Port

# The smaller dataset

      id      Port  
    456DEF  Boston Port
我有一个dataframe,它比较两个合并到同一dataframe中的不同数据集。需要注意的是,这两个数据帧的列数相同,但行数不同,因此一个是2979行,另一个是791行

较小的数据集在较大的数据集中有匹配的名称值,我正在尝试根据名称获取要匹配的行。如果值是唯一的,这很容易做到,只需使用dict映射,但警告如下:

  id      id2       Port1            Port2
123ABC   456DEF  Boston Port      Boston Port
789GHI   456DEF  Boston Port      Boston Port
波士顿有两个
端口
,但是它们的ID号不同(因为一个端口位于美国波士顿,另一个位于英国),dict/map会忽略这一点,并将第一个出现的端口作为匹配

示例df:

  id      id2       Port1            Port2
123ABC   456DEF  Boston Port      Boston Port
789GHI   101JKL  Boston Port      Bridport Harbour
第二个数据集(较小的一个)是基于一个较大数据库中的匹配名称创建的,但是名称不是唯一的,但其他属性是我稍后在代码工作流中用来区分它们的

这里的基本任务是确保
Port1
Port2
中的任何值对齐到同一行,并且任何重复项都与
Port1
匹配,因此理想情况下所需的输出如下所示:

  id      id2       Port1            Port2
123ABC   456DEF  Boston Port      Boston Port
789GHI   456DEF  Boston Port      Boston Port
这是我用来将两列映射到同一数据帧的代码片段:

all_ents = pd.concat([big_dataset, small_dataset], axis=1)  # Concat the two dataframes 

big_name_mapper = dict(zip(big_dataset.id1, big_dataset.name))  # Create Mapping dictionary from larger dataframe
small_name_mapper = dict(zip(small_dataset.id2, small_dataset.name))  # Create Mapping dictionary from smaller dataframe

all_ents['Port1'] = all_ents.id1.map(big_name_mapper)  # Create New column based on big_name_mapper
all_ents['Port2'] = all_ents.id2.map(small_name_mapper)  # Create New column based on small_name_mapper
有人有处理这件事的经验吗?谢谢

编辑2:最终代码

谢谢@Dave

这是我根据他的答案使用的最后一个代码,还有一些过滤,因为我不希望在这种情况下出现不匹配的行

Really_Big = BIG.merge(SMALL, how="outer", on="port", suffixes=(1, 2))

Really_Big = Really_Big[Really_Big['id1'].notnull()]
Really_Big = Really_Big[Really_Big['id2'].notnull()]  # Theres absolutely a much more efficient way to do this filter but for times sake this'll work.

让我们先考虑SQL。您有数据帧df1和df2,都有列Port和id,并且您询问是否有任何id不同,而Port相同。那么你在这么做

SELECT DISTINCT A.id, B.id, A.Port
FROM df1 A INNER JOIN df2 B ON A.Port=B.Port
WHERE A.id != B.id
在pandas dataframe中,您只需将上述SQL转换为pandas代码:

output = (
    df1.rename(columns={'id':'id1'})[['id1', 'Port']]
    .merge(df2.rename(columns={'id':'id2'})[['id2', 'Port']],
           on='Port',
           how='inner')
    .pipe(lambda df: df[df['id1'] 1= df['id2']])
    .drop_duplicates()
)

然后数据帧
输出将包含三列,
id1
id2
Port
,显示所有具有不同ID的端口。

看起来很像您想要加入大小数据集。 假设您有小的:

       id         Port
0  456DEF  Boston Port
而且很大:

       id              Port
0  123ABC       Boston Port
1  789GHI       Boston Port
2  101JKL  Bridport Harbour
将它们合并到
端口
将为您提供共享
端口的每一对大小
id

big\u数据集。合并(small\u数据集,how=“outer”,on=“Port”,后缀=(1,2))
如果端口仅出现在一个数据集中,则它将在输出中显示一次

      id1              Port     id2
0  123ABC       Boston Port  456DEF
1  789GHI       Boston Port  456DEF
2  101JKL  Bridport Harbour     NaN

如果你给出第一个和第二个数据帧的样子以及你想要的输出的样子的例子,那么你的问题就更容易理解了。@adrtam修复了,我在代码段的正上方陈述了理想输出的样子。我得到了一些对现有数据帧的未解决的引用(
df1
df2
),作为连接的一部分,
输出是否已经存在,或者是否正在重新定义?