使用 Pandas 从另一个数据帧中包含的值检测数据帧的索引
Detect indexes of a dataframe from values contained in another dataframe with Pandas
我有 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
注意:如果没有找到名字,则不需要存储任何信息。
我想你可以使用 merge
with 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]
您正在寻找方法 isin
:
df = df2[df2['XXX'].isin(nan_names)]
这将 return:
XXX
5 FIGO
6 FIGO
11 TNCO
12 TNCO
13 TNCO
从那里开始,只是格式问题:
df.reset_index().groupby('XXX')['index'].apply(list)
这将 return:
XXX
FIGO [5, 6]
TNCO [11, 12, 13]
想法是重置索引,使其成为一个列(名为 index
)。按名称分组并应用 list
函数将 return 每个名称的原始索引列表。
再次调用 reset_index
将 return 您正在寻找的结果。
编辑
将所有内容组合成一行,这将是输出:
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]
我有 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
注意:如果没有找到名字,则不需要存储任何信息。
我想你可以使用 merge
with 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]
您正在寻找方法 isin
:
df = df2[df2['XXX'].isin(nan_names)]
这将 return:
XXX
5 FIGO
6 FIGO
11 TNCO
12 TNCO
13 TNCO
从那里开始,只是格式问题:
df.reset_index().groupby('XXX')['index'].apply(list)
这将 return:
XXX
FIGO [5, 6]
TNCO [11, 12, 13]
想法是重置索引,使其成为一个列(名为 index
)。按名称分组并应用 list
函数将 return 每个名称的原始索引列表。
再次调用 reset_index
将 return 您正在寻找的结果。
编辑
将所有内容组合成一行,这将是输出:
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]