pandas python中的VLOOKUP Excel模拟

2024-09-30 02:21:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我有2个数据帧。在

df1:

index ID City         Region 2City
1     23 Moscow       Msk    
2     34 Obninsk      Msk    Msk
3     56                     Spb
4     17 Tula         Spb

df2:

^{pr2}$

我想得到以下数据:

index ID City         Region 2City Office
1     23 Moscow       Msk          Msk
2     34 Obninsk      Msk    Msk   Msk
3     56                     Spb   Spb
4     17 Tula         Spb          Msk

因此它检查df2中的'office'与df1中的'City''Region''2City'匹配。在

另外,如果我找到'office'作为'City',我就会停止搜索。所以'City'列有优先权,然后是'Region',然后是{}。在

我知道如何用3for来实现这一点,但我希望有更好的选择。在


Tags: 数据idcityindexregiondf1df2office
3条回答

通常在Pandas中使用join(默认为左连接)或merge(其中必须指定how='left')。在

在您的例子中,您尝试查找基于三列的值。一种方法是使用or获取第一个非空值。在

>>> (df1
     .assign(temp = [region or two_city or city 
                     for region, two_city, city in zip(df1.Region, df1['2City'], df1.City)])
     .merge(df2, how='left', right_on='City', left_on='temp', suffixes=['', '_'])
     .drop(['temp', 'City_'], axis=1))

   ID     City Region 2City Office
0  23   Moscow    Msk  None    Msk
1  34  Obninsk    Msk   Msk    Msk
2  56     None   None   Spb    Spb
3  17     Tula    Spb  None    Msk

您可以用^{}合并这两个数据帧,但据我所知,您实际上希望在df1中的不同列上合并。一种可能的方法是添加一个额外的列,该列的值为'City'(如果可用)(否则是'region'或{})。在

import pandas as pd

df1['Office'] = df1.City.fillna(df1.Region).fillna(df1['2City'])
df = pd.merge(df1, df2.reindex(columns='Office'), on='Office')

您不需要指定两个数据帧中是否缺少值。如果是这样,您可以使用how参数控制它们的处理pd.merge。在

import pandas as pd
df1 = pd.DataFrame([[23, 'Moscow', 'Msk', ''],
                    [34, 'Obninsk', 'Msk', 'Msk'],
                    [56, '', '', 'Spb'],
                    [17, 'Tula', 'Spb', '']],
                   columns=['ID', 'City', 'Region', '2City'])
df2 = pd.DataFrame([['Msk', 'Msk'],
                    ['Spb', 'Spb'],
                    ['Tula', 'Msk'],
                    ['Moscow', 'Msk']],
                   columns=['City', 'Office'])

df = pd.concat([df1.loc[df1[x].isin(df2['City']), x] for x in ['City', 'Region', '2City']])
df1['Join'] = df.groupby(df.index).first()
output = df1.merge(df2, left_on='Join', right_on='City', how='right')

此时,名为“output”的pandas.DataFrame将包含一个名为“Office”的列,该列的索引与df1相匹配。你可以这样做:

^{pr2}$

这将为您提供所请求的数据帧以及附加列“Join”,您可以通过以下方式删除:

df1.drop('Join', axis=1, inplace=True)

这里的OP基本上想做三个单独的合并——在df1中的“City”、“Region”和“2City”列中的每一个合并。因此,在没有体操的情况下使用基本的pandas.DataFrame操作是不容易做到的。我只是在列表理解中隐藏了for循环,但它仍然存在。在

相关问题 更多 >

    热门问题