<p>这里有一个递归的<code>apply</code>函数来实现这一点。函数接受一个<code>id</code>并通过树返回其“路径”:</p>
<pre><code>def flatname(ID):
row = df[df['id'] == ID].squeeze()
if row['parent_id'] == -1:
return row['name']
else:
return flatname(row['parent_id']) + ' : ' + row['name']
</code></pre>
<p>要使用,请致电:</p>
<pre><code>df['flat_name'] = df['id'].apply(flatname)
</code></pre>
<p>在第二个示例中使用后的<code>df</code>:</p>
<pre><code> id name parent_id flat_name
0 1 Linear Asset -1 Linear Asset
1 2 Lateral 1 Linear Asset : Lateral
2 3 Main 1 Linear Asset : Main
3 4 Point Asset -1 Point Asset
4 5 Fountain 4 Point Asset : Fountain
5 6 Hydrant 4 Point Asset : Hydrant
6 7 Steel 2 Linear Asset : Lateral : Steel
7 8 Plastic 2 Linear Asset : Lateral : Plastic
8 9 Steel 3 Linear Asset : Main : Steel
9 10 Plastic 3 Linear Asset : Main : Plastic
</code></pre>
<hr/>
<p>OP注意到上面的函数显式地引用了在函数范围之外定义的<code>df</code>变量。因此,如果您将数据帧称为不同的名称,或者您希望在许多数据帧上调用此名称,这可能会导致问题。一种修复方法是将<code>apply</code>函数转变为更像私人助手的函数,并创建一个调用它的外部(更用户友好)函数:</p>
<pre><code>def _flatname_recurse(ID, df):
row = df[df['id'] == ID].squeeze()
if row['parent_id'] == -1:
return row['name']
else:
return _flatname_recurse(row['parent_id'], df=df) + ' : ' + row['name']
# asset_df to specify we are looking for a specific kind of df
def flatnames(asset_df):
return asset_df['id'].apply(_flatname_recurse, df=asset_df)
</code></pre>
<p>然后致电:</p>
<pre><code>df['flat_name'] = flatnames(df)
</code></pre>
<p>另外,请注意,我曾经使用<code>row = df.iloc[ID - 1, :]</code>来标识行,这在本例中有效,但取决于<code>id</code>比索引大一<a href="https://stackoverflow.com/a/19599661/13386979">This approach</a>更一般</p>