我有一个数据帧,它有两列level1和level2。级别1中的每个帐号都链接到列级别2中的ParentID。对于以";8409";在列";级别1";其中一些被映射到级别2中错误的ParentID。为了找到正确的ParentID,你需要在级别1中搜索,在那里你替换所有以"结尾的帐户;8409";用";8400";。然后,它将在同一列中找到其等效帐户。在找到匹配的地方,复制列"中的内容;级别2";并将其替换为以";8409";。
import pandas as pd
import numpy as np
df = pd.DataFrame([[7854568400,489],
[9632588400,126],
[3699633691,189],
[9876543697,987],
[1111118409,987],
[7854568409,396],
[7854567893,897],
[9632588409,147]],
columns = ['level1','level2'])
df
下面的解决方案允许创建一个新的列";new_level2";以解决上述问题。
maps = df.set_index('level1')['level2']
s = df['level1'].astype(str).str.replace('8409$', '8400', regex=True).astype('int64')
df['new_level2'] = s.map(maps).combine_first(df['level2']).convert_dtypes()
在下面的输出中,account";7854568409〃;其级别2从396变为489(取自第0行(;9632588409";其级别2从147变为126(取自第1行(。
level1 level2 new_level2
0 7854568400 489 489
1 9632588400 126 126
2 3699633691 189 189
3 9876543697 987 987
4 1111118409 987 987
5 7854568409 396 489
6 7854567893 897 897
7 9632588409 147 126
然而,当我将上面的解决方案应用于其他变量时,这就是我遇到问题的地方,主要是当我将货币添加到数据帧时。级别2值的替换仅适用于美元,所有其他货币都需要在级别2列中保留其当前值。
旧DF
df = pd.DataFrame([['USD',7854568400,489],
['USD',9632588400,126],
['USD',3699633691,189],
['USD',9876543697,987],
['EUR',1111118409,987],
['USD',1111118409,987],
['USD',7854568409,396],
['USD',7854567893,897],
['USD',9632588409,147]],
columns = ['cur','level1','level2'])
df
修订DF
df = pd.DataFrame([['USD',7854568400,489],
['USD',9632588400,126],
['USD',3699633691,189],
['USD',9876543697,987],
['EUR',1111118400,120],
['EUR',1111118409,987],
['USD',1111118409,987],
['USD',7854568409,396],
['USD',7854567893,897],
['USD',9632588409,147]],
columns = ['cur','level1','level2'])
当我试图将上面的解决方案应用于包含货币的新数据帧时,我得到了以下错误。InvalidIndexError: Reindexing only valid with uniquely valued Index objects
值得注意的是,不同货币之间可以有相同的账号。
所需输出低于。只有2个账户(9632588409和7854568409(的级别2发生了变化。指数4和5应保留其原始的2级价值,因为它们是欧元,不在范围内;指数6应保留其初始价值,因为找不到该账户的相应匹配项,因此保留其原始价值。
cur level1 level2 new_level2
0 USD 7854568400 489 489
1 USD 9632588400 126 126
2 USD 3699633691 189 189
3 USD 9876543697 987 987
4 EUR 1111118400 120 120
5 EUR 1111118409 987 987
6 USD 1111118409 987 987
7 USD 7854568409 396 489
8 USD 7854567893 897 897
9 USD 9632588409 147 126
非常感谢您的帮助。
df = pd.DataFrame([['USD',7854568400,489],
['USD',9632588400,126],
['USD',3699633691,189],
['USD',9876543697,987],
['EUR',1111118400,120],
['EUR',1111118409,987],
['USD',1111118409,987],
['USD',7854568409,396],
['USD',7854567893,897],
['USD',9632588409,147]],
columns = ['cur','level1','level2'])
df['level1'] = df['level1'].astype(str).str.replace('8409$', '8400', regex=True).astype('int64')
df['new_col'] = df.where(df['cur'] == 'USD').groupby(['level1', 'cur'])['level2']
.transform('first').fillna(df['level2']).astype(int)
print(df)
cur level1 level2 new_col
0 USD 7854568400 489 489
1 USD 9632588400 126 126
2 USD 3699633691 189 189
3 USD 9876543697 987 987
4 EUR 1111118400 120 120
5 EUR 1111118400 987 987
6 USD 1111118400 987 987
7 USD 7854568400 396 489
8 USD 7854567893 897 897
9 USD 9632588400 147 126