Python - Pandas mapping error: Reindexing only valid with uniquely valued Index objects
Python - Pandas mapping error: Reindexing only valid with uniquely valued Index objects
我正在开发一个函数,该函数旨在根据两个字段(Ticker 或 CUSIP)之一将 ID 从一个数据帧映射到另一个数据帧。主 df 是一个保管人文件,其中包含以下字段:
Ticker
CUSIP
0
AAA
NaN
1
ABC
NaN
2
NaN
123456789
3
UNK
NaN
map_df 是内部下载的辅助文件,它将保管人文件 (df) 映射到第一次将证券输入我们的系统时生成的任意“Owned_ID”。它看起来像:
Owned_ID
Ticker
CUSIP
0
0
AAA
1
11
ABC
111111111
2
22
NaN
123456789
3
33
4
44
我的目标是创建一个文件,将 CUSIP 映射到映射文件以提取拥有的 ID。如果 CUSIP 不可用,那么它应该使用 Ticker 并提取一个 Owned ID。如果在映射文件中找不到 CUSIP 和 Ticker,则可以 return NaN。因此输出数据框应该是这样的:
Ticker
CUSIP
Owned_ID
0
AAA
NaN
0
1
ABC
NaN
11
2
NaN
123456789
22
3
UNK
NaN
NaN
我想出了下面的代码,它基本上通过重新索引来映射数据帧,但将 运行 保留在错误中:
File "C:\Users\JeffNi\PycharmProjects\KP21 - Addepar Upload Generator\Archives\OwnedID Match Sample.py", line 41, in <module>
df['Owned_ID'] = np.where(mask_a, df['CUSIP'].map(a)
File "C:\Users\JeffNi\anaconda3\lib\site-packages\pandas\core\series.py", line 3909, in map
new_values = super()._map_values(arg, na_action=na_action)
File "C:\Users\JeffNi\anaconda3\lib\site-packages\pandas\core\base.py", line 907, in _map_values
indexer = mapper.index.get_indexer(values)
File "C:\Users\JeffNi\anaconda3\lib\site-packages\pandas\core\indexes\base.py", line 3171, in get_indexer
raise InvalidIndexError(
InvalidIndexError: Reindexing only valid with uniquely valued Index objects
这是我用来重现此错误的代码片段。
import pandas as pd
df = pd.DataFrame({'Ticker': {0: 'AAA', 1: 'ABC', 2: pd.NA, 3:'UNK'},
'CUSIP': {0: pd.NA, 1: pd.NA, 2: '123456789', 3:pd.NA}})
df_map = pd.DataFrame(
{'Owned_ID' : {0: '11', 1: '22', 2: '33', 3:'44', 4:'55'},
'Ticker': {0: 'AAA', 1: 'ABC', 2: pd.NA, 3:pd.NA, 4:pd.NA},
'CUSIP': {0: pd.NA, 1: '111111111', 2: '123456789', 3:pd.NA, 4:pd.NA}})
a = df_map.set_index('CUSIP')['Owned_ID']
b = df_map.set_index('Ticker')['Owned_ID']
mask_a = df['CUSIP'].isnull()
df['Owned_ID'] = np.where(mask_a, df['CUSIP'].map(a), df['Ticker'].map(b))
print(df)
我认为这可能与具有 NA 形式的重复项的映射文件有关,但我无法弄清楚我需要做什么才能使索引工作(或者如果有解决这个问题的更好方法)。我想它类似于 Excel 中的 Vlookup 函数,我在 map_df 中查找 CUSIP,如果失败,则在 map_df 中查找 Ticker,如果失败则只是 return错误。
感谢任何意见!
您应该首先删除映射数据帧的 na 值:
a = df_map.dropna(subset=["CUSIP"]).set_index('CUSIP')['Owned_ID']
b = df_map.dropna(subset=["Ticker"]).set_index('Ticker')['Owned_ID']
mask_a = df['CUSIP'].isnull()
df['Owned_ID'] = np.where(mask_a, df['Ticker'].map(b), df['CUSIP'].map(a))
请注意,您还需要交换 np.where
参数,因为它们是错误的。
为了显示这是您想要的顺序:
df = pd.DataFrame({'Ticker': {0: 'AAA', 1: 'ABC', 2: "test", 3:'UNK'},
'CUSIP': {0: pd.NA, 1: pd.NA, 2: '123456789', 3:pd.NA}})
df_map = pd.DataFrame(
{'Owned_ID' : {0: '11', 1: '22', 2: '33', 3:'44', 4:'55', 5: "66"},
'Ticker': {0: 'AAA', 1: 'ABC', 2: pd.NA, 3:pd.NA, 4:pd.NA, 5: "test"},
'CUSIP': {0: pd.NA, 1: '111111111', 2: '123456789', 3:pd.NA, 4:pd.NA, 5:pd.NA}})
a = df_map.dropna(subset=["CUSIP"]).set_index('CUSIP')['Owned_ID']
b = df_map.dropna(subset=["Ticker"]).set_index('Ticker')['Owned_ID']
mask_a = df['CUSIP'].isnull()
df['Owned_ID'] = np.where(mask_a, df['Ticker'].map(b), df['CUSIP'].map(a))
print(df)
# Ticker CUSIP Owned_ID
#0 AAA <NA> 11
#1 ABC <NA> 22
#2 test 123456789 33
#3 UNK <NA> NaN
索引“2”是 33,而不是这里的 66,所以使用了 CUSIP,因为它可用。
我正在开发一个函数,该函数旨在根据两个字段(Ticker 或 CUSIP)之一将 ID 从一个数据帧映射到另一个数据帧。主 df 是一个保管人文件,其中包含以下字段:
Ticker | CUSIP | |
---|---|---|
0 | AAA | NaN |
1 | ABC | NaN |
2 | NaN | 123456789 |
3 | UNK | NaN |
map_df 是内部下载的辅助文件,它将保管人文件 (df) 映射到第一次将证券输入我们的系统时生成的任意“Owned_ID”。它看起来像:
Owned_ID | Ticker | CUSIP | |
---|---|---|---|
0 | 0 | AAA | |
1 | 11 | ABC | 111111111 |
2 | 22 | NaN | 123456789 |
3 | 33 | ||
4 | 44 |
我的目标是创建一个文件,将 CUSIP 映射到映射文件以提取拥有的 ID。如果 CUSIP 不可用,那么它应该使用 Ticker 并提取一个 Owned ID。如果在映射文件中找不到 CUSIP 和 Ticker,则可以 return NaN。因此输出数据框应该是这样的:
Ticker | CUSIP | Owned_ID | |
---|---|---|---|
0 | AAA | NaN | 0 |
1 | ABC | NaN | 11 |
2 | NaN | 123456789 | 22 |
3 | UNK | NaN | NaN |
我想出了下面的代码,它基本上通过重新索引来映射数据帧,但将 运行 保留在错误中:
File "C:\Users\JeffNi\PycharmProjects\KP21 - Addepar Upload Generator\Archives\OwnedID Match Sample.py", line 41, in <module>
df['Owned_ID'] = np.where(mask_a, df['CUSIP'].map(a)
File "C:\Users\JeffNi\anaconda3\lib\site-packages\pandas\core\series.py", line 3909, in map
new_values = super()._map_values(arg, na_action=na_action)
File "C:\Users\JeffNi\anaconda3\lib\site-packages\pandas\core\base.py", line 907, in _map_values
indexer = mapper.index.get_indexer(values)
File "C:\Users\JeffNi\anaconda3\lib\site-packages\pandas\core\indexes\base.py", line 3171, in get_indexer
raise InvalidIndexError(
InvalidIndexError: Reindexing only valid with uniquely valued Index objects
这是我用来重现此错误的代码片段。
import pandas as pd
df = pd.DataFrame({'Ticker': {0: 'AAA', 1: 'ABC', 2: pd.NA, 3:'UNK'},
'CUSIP': {0: pd.NA, 1: pd.NA, 2: '123456789', 3:pd.NA}})
df_map = pd.DataFrame(
{'Owned_ID' : {0: '11', 1: '22', 2: '33', 3:'44', 4:'55'},
'Ticker': {0: 'AAA', 1: 'ABC', 2: pd.NA, 3:pd.NA, 4:pd.NA},
'CUSIP': {0: pd.NA, 1: '111111111', 2: '123456789', 3:pd.NA, 4:pd.NA}})
a = df_map.set_index('CUSIP')['Owned_ID']
b = df_map.set_index('Ticker')['Owned_ID']
mask_a = df['CUSIP'].isnull()
df['Owned_ID'] = np.where(mask_a, df['CUSIP'].map(a), df['Ticker'].map(b))
print(df)
我认为这可能与具有 NA 形式的重复项的映射文件有关,但我无法弄清楚我需要做什么才能使索引工作(或者如果有解决这个问题的更好方法)。我想它类似于 Excel 中的 Vlookup 函数,我在 map_df 中查找 CUSIP,如果失败,则在 map_df 中查找 Ticker,如果失败则只是 return错误。
感谢任何意见!
您应该首先删除映射数据帧的 na 值:
a = df_map.dropna(subset=["CUSIP"]).set_index('CUSIP')['Owned_ID']
b = df_map.dropna(subset=["Ticker"]).set_index('Ticker')['Owned_ID']
mask_a = df['CUSIP'].isnull()
df['Owned_ID'] = np.where(mask_a, df['Ticker'].map(b), df['CUSIP'].map(a))
请注意,您还需要交换 np.where
参数,因为它们是错误的。
为了显示这是您想要的顺序:
df = pd.DataFrame({'Ticker': {0: 'AAA', 1: 'ABC', 2: "test", 3:'UNK'},
'CUSIP': {0: pd.NA, 1: pd.NA, 2: '123456789', 3:pd.NA}})
df_map = pd.DataFrame(
{'Owned_ID' : {0: '11', 1: '22', 2: '33', 3:'44', 4:'55', 5: "66"},
'Ticker': {0: 'AAA', 1: 'ABC', 2: pd.NA, 3:pd.NA, 4:pd.NA, 5: "test"},
'CUSIP': {0: pd.NA, 1: '111111111', 2: '123456789', 3:pd.NA, 4:pd.NA, 5:pd.NA}})
a = df_map.dropna(subset=["CUSIP"]).set_index('CUSIP')['Owned_ID']
b = df_map.dropna(subset=["Ticker"]).set_index('Ticker')['Owned_ID']
mask_a = df['CUSIP'].isnull()
df['Owned_ID'] = np.where(mask_a, df['Ticker'].map(b), df['CUSIP'].map(a))
print(df)
# Ticker CUSIP Owned_ID
#0 AAA <NA> 11
#1 ABC <NA> 22
#2 test 123456789 33
#3 UNK <NA> NaN
索引“2”是 33,而不是这里的 66,所以使用了 CUSIP,因为它可用。