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,因为它可用。