在Pandas中按索引和名称查找数值

huangapple go评论101阅读模式
英文:

Lookup value by index and name in Pandas

问题

我有一个带有扁平化层次结构的pandas数据框:

Level 1 ID Level 2 ID Level 3 ID Level 4 ID Name Path
1 null null null Finance Finance
1 4 null null Reporting Finance > Reporting
1 4 5 null Tax Reporting Finance > Reporting > Tax Reporting

我想要做的是根据Level ID列添加或替换为4个Level Name列,如下所示:

Level 1 Name Level 2 Name Level 3 Name Level 4 Name Name Path
Finance null null null Finance Finance
Finance Reporting null null Reporting Finance > Reporting
Finance Reporting Tax Reporting null Tax Reporting Finance > Reporting > Tax Reporting

我会在Path列上使用分隔符,但在实际的数据框中,存在ID而不是名称(格式化为"1 > 4 > 5")。

我应该如何处理这个问题?

df.info()的输出如下:

  1. df.info()
  2. <class 'pandas.core.frame.DataFrame'>
  3. RangeIndex: 135 entries, 0 to 134
  4. Data columns (total 8 columns):
  5. # Column Non-Null Count Dtype
  6. --- ------ -------------- -----
  7. 0 name 135 non-null object
  8. 1 depid 135 non-null object
  9. 2 depcode 135 non-null object
  10. 3 parentpath 135 non-null object
  11. 4 DEP_LV1_ID 135 non-null object
  12. 5 DEP_LV2_ID 135 non-null object
  13. 6 DEP_LV3_ID 98 non-null object
  14. 7 DEP_LV4_ID 56 non-null object
  15. dtypes: object(8)
  16. memory usage: 8.6+ KB
英文:

I have a pandas dataframe with a flattened hierarchy:

Level 1 ID Level 2 ID Level 3 ID Level 4 ID Name Path
1 null null null Finance Finance
1 4 null null Reporting Finance > Reporting
1 4 5 null Tax Reporting Finance > Reporting > Tax Reporting

What I want to do is add or replace with the Level ID columns with 4 Level Name columns based on the Level [] ID columns, like the following:

Level 1 Name Level 2 Name Level 3 Name Level 4 Name Name Path
Finance null null null Finance Finance
Finance Reporting null null Reporting Finance > Reporting
Finance Reporting Tax Reporting null Tax Reporting Finance > Reporting > Tax Reporting

I would use a separator on the Path column, but in the real dataframe, there are IDs instead of names (formatted like "1 > 4 > 5")

How should I approach this?

Output of df.info() is the following:

  1. df.info()
  2. &lt;class &#39;pandas.core.frame.DataFrame&#39;&gt;
  3. RangeIndex: 135 entries, 0 to 134
  4. Data columns (total 8 columns):
  5. # Column Non-Null Count Dtype
  6. --- ------ -------------- -----
  7. 0 name 135 non-null object
  8. 1 depid 135 non-null object
  9. 2 depcode 135 non-null object
  10. 3 parentpath 135 non-null object
  11. 4 DEP_LV1_ID 135 non-null object
  12. 5 DEP_LV2_ID 135 non-null object
  13. 6 DEP_LV3_ID 98 non-null object
  14. 7 DEP_LV4_ID 56 non-null object
  15. dtypes: object(8)
  16. memory usage: 8.6+ KB

答案1

得分: 1

以下是翻译好的部分:

假设源是 df[&#39;Name&#39;]
  1. cols = df.filter(like=&#39;Level &#39;).columns
  2. names = df[&#39;Name&#39;].values
  3. mask = df[cols[:len(names)]].notna()
  4. df[cols[:len(names)]] = mask.mul(names, axis=1).where(mask)

输出:

  1. Level 1 ID Level 2 ID Level 3 ID Level 4 ID Name Path
  2. 0 Finance NaN NaN NaN Finance Finance
  3. 1 Finance Reporting NaN NaN Reporting Finance &gt; Reporting
  4. 2 Finance Reporting Tax Reporting NaN Tax Reporting Finance &gt; Reporting &gt; Tax Reporting
如果您更喜欢从 "Path" 中提取
  1. cols = df.filter(like=&#39;Level &#39;).columns
  2. names = df[&#39;Path&#39;].str.split(&#39; &gt; &#39;, expand=True)
  3. df.loc[:, cols[:names.shape[1]]] = names.to_numpy()

输出:

  1. Level 1 ID Level 2 ID Level 3 ID Level 4 ID Name Path
  2. 0 Finance None None NaN Finance Finance
  3. 1 Finance Reporting None NaN Reporting Finance &gt; Reporting
  4. 2 Finance Reporting Tax Reporting NaN Tax Reporting Finance &gt; Reporting &gt; Tax Reporting
可复现的输入:
  1. import pandas as pd
  2. from numpy import nan
  3. df = pd.DataFrame({&#39;Level 1 ID&#39;: [1, 1, 1],
  4. &#39;Level 2 ID&#39;: [nan, 4.0, 4.0],
  5. &#39;Level 3 ID&#39;: [nan, nan, 5.0],
  6. &#39;Level 4 ID&#39;: [nan, nan, nan],
  7. &#39;Name&#39;: [&#39;Finance&#39;, &#39;Reporting&#39;, &#39;Tax Reporting&#39;],
  8. &#39;Path&#39;: [&#39;Finance&#39;, &#39;Finance &gt; Reporting&#39;, &#39;Finance &gt; Reporting &gt; Tax Reporting&#39;]}
  9. )
英文:

The logic is unclear, in particular what is the source of the final values? See two different options below.

Assuming the source is df[&#39;Name&#39;]
  1. cols = df.filter(like=&#39;Level &#39;).columns
  2. names = df[&#39;Name&#39;].values
  3. mask = df[cols[:len(names)]].notna()
  4. df[cols[:len(names)]] = mask.mul(names, axis=1).where(mask)

Output:

  1. Level 1 ID Level 2 ID Level 3 ID Level 4 ID Name Path
  2. 0 Finance NaN NaN NaN Finance Finance
  3. 1 Finance Reporting NaN NaN Reporting Finance &gt; Reporting
  4. 2 Finance Reporting Tax Reporting NaN Tax Reporting Finance &gt; Reporting &gt; Tax Reporting
If you rather want to extract from "Path"
  1. cols = df.filter(like=&#39;Level &#39;).columns
  2. names = df[&#39;Path&#39;].str.split(&#39; &gt; &#39;, expand=True)
  3. df.loc[:, cols[:names.shape[1]]] = names.to_numpy()

Output:

  1. Level 1 ID Level 2 ID Level 3 ID Level 4 ID Name Path
  2. 0 Finance None None NaN Finance Finance
  3. 1 Finance Reporting None NaN Reporting Finance &gt; Reporting
  4. 2 Finance Reporting Tax Reporting NaN Tax Reporting Finance &gt; Reporting &gt; Tax Reporting
reproducible input:
  1. import pandas as pd
  2. from numpy import nan
  3. df = pd.DataFrame({&#39;Level 1 ID&#39;: [1, 1, 1],
  4. &#39;Level 2 ID&#39;: [nan, 4.0, 4.0],
  5. &#39;Level 3 ID&#39;: [nan, nan, 5.0],
  6. &#39;Level 4 ID&#39;: [nan, nan, nan],
  7. &#39;Name&#39;: [&#39;Finance&#39;, &#39;Reporting&#39;, &#39;Tax Reporting&#39;],
  8. &#39;Path&#39;: [&#39;Finance&#39;, &#39;Finance &gt; Reporting&#39;, &#39;Finance &gt; Reporting &gt; Tax Reporting&#39;]}
  9. )

答案2

得分: 1

你可以创建一个映射系列来解析数字 -> 名称:

  1. url = 'https://drive.google.com/uc?id=1-2YXvyb8QEtHrrAO0UCH6vSJ5ww6CCjK&amp;export=download'
  2. df = pd.read_excel(url, index_col=0)
  3. cols = df.columns[df.columns.str.contains('DEP_LV\d_ID')]
  4. idx = df[cols].ffill(axis=1).iloc[:, -1].tolist()
  5. sr = pd.Series(df['name'].tolist(), index=idx)
  6. df[cols] = df[cols].apply(lambda x: x.map(sr))

输出:

  1. &gt;&gt;&gt; df
  2. name depid depcode parentpath DEP_LV1_ID DEP_LV2_ID DEP_LV3_ID DEP_LV4_ID
  3. 0 Дотоод аудитын хэлтэс 152 61100 |152| Дотоод аудитын хэлтэс NaN NaN NaN
  4. 1 Санхүү бүртгэлийн газар 214 31000 |214| Санхүү бүртгэлийн газар NaN NaN NaN
  5. 2 Хүний нөөцийн бодлого, төлөвлөлтийн хэлтэс 211 32100 |209|211| Хүний нөөцийн газар Хүний нөөцийн бодлого, төлөвлөлтийн хэлтэс NaN NaN
  6. 3 Санхүү бүртгэлийн хэлтэс 215 31100 |214|215| Санхүү бүртгэлийн газар Санхүү бүртгэлийн хэлтэс NaN NaN
  7. 4 Хүний нөөцийн газар 209 32000 |209| Хүний нөөцийн газар NaN NaN NaN
  8. .. ... ... ... ... ... ... ... ...
  9. 130 Оёх нэгж (C1) 816 20512 |511|522|811|816| Үйлдвэр удирдлагын газар Сүлжмэлийн үйлдвэр Сүлжмэлийн 1-р алба Оёх нэгж (C1)
  10. 131 Галлериа УБ нэгж 867 11209 |857|859|867| Дотоод борлуулалтын газар Дотоод борлуулалтын хэлтэс Галлериа УБ нэгж NaN
  11. 132 Хими цэвэрлэгээ, нөхөн засварын алба 870 11230 |857|859|870| Дотоод борлуулалтын газар Дотоод борлуулалтын хэлтэс Хими цэвэрлэгээ, нөхөн засварын алба NaN
  12. 133 Дархан нэгж 868 11205 |857|859|868| Дотоод борлуулалтын газар Дотоод борлуулалтын хэлтэс Дархан нэгж NaN
  13. 134 Төв дэлгүүр нэгж 869 11201 |857|859|869| Дотоод борлуулалтын газар Дотоод борлуулалтын хэлтэс Төв дэлгүүр нэгж NaN
  14. [135 rows x 8 columns]
英文:

You can create a mapping Series to resolve number -> name:

  1. url = &#39;https://drive.google.com/uc?id=1-2YXvyb8QEtHrrAO0UCH6vSJ5ww6CCjK&amp;export=download&#39;
  2. df = pd.read_excel(url, index_col=0)
  3. cols = df.columns[df.columns.str.contains(&#39;DEP_LV\d_ID&#39;)]
  4. idx = df[cols].ffill(axis=1).iloc[:, -1].tolist()
  5. sr = pd.Series(df[&#39;name&#39;].tolist(), index=idx)
  6. df[cols] = df[cols].apply(lambda x: x.map(sr))

Output:

  1. &gt;&gt;&gt; df
  2. name depid depcode parentpath DEP_LV1_ID DEP_LV2_ID DEP_LV3_ID DEP_LV4_ID
  3. 0 Дотоод аудитын хэлтэс 152 61100 |152| Дотоод аудитын хэлтэс NaN NaN NaN
  4. 1 Санхүү бүртгэлийн газар 214 31000 |214| Санхүү бүртгэлийн газар NaN NaN NaN
  5. 2 Хүний нөөцийн бодлого, төлөвлөлтийн хэлтэс 211 32100 |209|211| Хүний нөөцийн газар Хүний нөөцийн бодлого, төлөвлөлтийн хэлтэс NaN NaN
  6. 3 Санхүү бүртгэлийн хэлтэс 215 31100 |214|215| Санхүү бүртгэлийн газар Санхүү бүртгэлийн хэлтэс NaN NaN
  7. 4 Хүний нөөцийн газар 209 32000 |209| Хүний нөөцийн газар NaN NaN NaN
  8. .. ... ... ... ... ... ... ... ...
  9. 130 Оёх нэгж (C1) 816 20512 |511|522|811|816| Үйлдвэр удирдлагын газар Сүлжмэлийн үйлдвэр Сүлжмэлийн 1 алба Оёх нэгж (C1)
  10. 131 Галлериа УБ нэгж 867 11209 |857|859|867| Дотоод борлуулалтын газар Дотоод борлуулалтын хэлтэс Галлериа УБ нэгж NaN
  11. 132 Хими цэвэрлэгээ, нөхөн засварын алба 870 11230 |857|859|870| Дотоод борлуулалтын газар Дотоод борлуулалтын хэлтэс Хими цэвэрлэгээ, нөхөн засварын алба NaN
  12. 133 Дархан нэгж 868 11205 |857|859|868| Дотоод борлуулалтын газар Дотоод борлуулалтын хэлтэс Дархан нэгж NaN
  13. 134 Төв дэлгүүр нэгж 869 11201 |857|859|869| Дотоод борлуулалтын газар Дотоод борлуулалтын хэлтэс Төв дэлгүүр нэгж NaN
  14. [135 rows x 8 columns]

huangapple
  • 本文由 发表于 2023年1月9日 15:16:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/75054142.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定