使用Pandas从包含在另一个数据帧中的值中检测数据帧的索引

时间:2016-11-24 09:01:23

标签: python pandas numpy nan

我有2个数据帧:

# dataframe 1
data = {'Name':['PINO','PALO','TNCO' ,'TNTO','CUCO' ,'FIGO','ONGF','LABO'],
        'Id'  :[  10  ,  9   ,np.nan ,  14   , 3    ,np.nan,  7   ,np.nan]}
df1 = pd.DataFrame(data)

# dataframe 2
convert_table = {'XXX': ['ALLO','BELO','CACO','CUCO','DADO','FIGO','FIGO','ONGF','PALO','PALO','PINO','TNCO','TNCO','TNCO','TNTO']}
df2 = pd.DataFrame(convert_table)

我的目标是确定符合以下条件的df2['XXX']元素的索引:

  • 出现在df1['Name']
  • 有对手df1['Id'] = NaN

我能够通过使用以下代码行来实现我的目标:

nan_names = df1['Name'][df1['Id'].isnull()]

df3 = pd.DataFrame()
for name in nan_names:
    index = df2[df2['XXX']==name].index.tolist()
    if index:
        dic = {'name':[name] , 'index':[index]}
        df3 = pd.concat([df3,pd.DataFrame(dic)], ignore_index=True)

但是我想知道是否有更有效和更优雅的方式来实现我的目标。

结果应如下所示:

          index  name
0  [11, 12, 13]  TNCO
1        [5, 6]  FIGO

注意:如果找不到名称,则不需要存储任何信息。

2 个答案:

答案 0 :(得分:2)

我认为您可以将mergegroupbyapply list一起使用:

nan_names = df1.loc[df1['Id'].isnull(), ['Name']]
print (nan_names)
   Name
2  TNCO
5  FIGO
7  LABO

df = pd.merge(df2.reset_index(), nan_names, on='Name', suffixes=('','_'))
print (df)
   index  Name
0      5  FIGO
1      6  FIGO
2     11  TNCO
3     12  TNCO
4     13  TNCO

print (df.groupby('Name')['index'].apply(list).reset_index())
   Name         index
0  FIGO        [5, 6]
1  TNCO  [11, 12, 13]

答案 1 :(得分:2)

您正在寻找方法isin

df = df2[df2['XXX'].isin(nan_names)]

这将返回:

    XXX
5   FIGO
6   FIGO
11  TNCO
12  TNCO
13  TNCO

从那里只是格式化问题:

df.reset_index().groupby('XXX')['index'].apply(list)

这将返回:

XXX
FIGO          [5, 6]
TNCO    [11, 12, 13]

我们的想法是重置索引,使其成为一个列(名为index)。按名称分组并应用list函数将返回每个名称的原始索引列表。

再次呼叫reset_index将返回您要查找的结果。

修改

将所有内容组合成一个单行,这将是输出:

In [21]: df2[df2['XXX'].isin(nan_names)].reset_index().groupby('XXX')['index'].apply(list).reset_index()
Out[21]: 
   XXX         index
0  FIGO        [5, 6]
1  TNCO  [11, 12, 13]