我有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
注意:如果找不到名称,则不需要存储任何信息。
答案 0 :(得分:2)
我认为您可以将merge
与groupby
和apply
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]