pandas 使用嵌套字典的 int 键替换数据帧浮点值

pandas replace dataframe float values using int keys of nested dict

我有如下所示的数据框和字典

ID,Name,value,total,     
1,Ajay,2.00,35          
1,Dan,3.00,65
2,Ajay,2,78
2,Rajini,0.0,98           
3,Ajay,3.00,53    
3,Rad,75.25,21

df1 = pd.read_clipboard(sep=',')

output = {'Ajay': {1: 'ABC', 2: 'DEF', 3: 'DUMMA', 4: 'CHUMMA'}, 'Dan': {0: 'KOREA', 1: 'AUS/NZ', 2: 'INDIA', 3: 'ASEAN'}}

我想执行以下操作

a) 通过将 Name 值与嵌套字典中的 Name 键匹配来替换 value 列中的值。

例如:ID=1 的名称为 Ajay,值为 2.00

现在,如果我们查看字典,我们会 Ajay 外键并尝试找到匹配的键(即 2)。因此,我们将值 2.00 替换为 DEF.

同样,我们为其他名称执行此操作 Dan

我尝试了以下

df1.replace({"values": output},inplace=True)  # doesn't work
for d in output.values():
    print(d.key())  

是否有任何有效且优雅的方法来对百万行数据帧进行这种替换?

我希望我的输出如下所示

您可以尝试循环字典,然后使用 df.masknp.whereloc 和布尔索引来替换值。

for k, v in output.items():
    df['value'] = df['value'].mask(df['Name'].eq(k), df['value'].map(v))
    #df['value'] = np.where(df['Name'].eq(k), df['value'].map(v), df['value'])
    #df.loc[df['Name'].eq(k), 'value'] = df.loc[df['Name'].eq(k), 'value'].map(v)
print(df)

   ID    Name  value  total
0   1    Ajay    DEF     35
1   1     Dan  ASEAN     65
2   2    Ajay    DEF     78
3   2  Rajini    0.0     98
4   3    Ajay  DUMMA     53
5   3     Rad  75.25     21

使用 DataFrame.join with DataFrame.stack for new column and then use Series.fillna 将不匹配的值替换为 value 列:

df = df.join(pd.DataFrame(output).stack().rename('new'), on=['value','Name'])
df['value'] = df.pop('new').fillna(df['value'])
print (df)
   ID    Name  value  total
0   1    Ajay    DEF     35
1   1     Dan  ASEAN     65
2   2    Ajay    DEF     78
3   2  Rajini    0.0     98
4   3    Ajay  DUMMA     53
5   3     Rad  75.25     21

试试这个

# map value-Names to output and fill the missing values with original values
df1['value'] = pd.Series(df1.set_index(['value','Name']).index.map(pd.DataFrame(output).stack())).fillna(df1['value'])
print(df1)
   ID    Name  value  total
0   1    Ajay    DEF     35
1   1     Dan  ASEAN     65
2   2    Ajay    DEF     78
3   2  Rajini    0.0     98
4   3    Ajay  DUMMA     53
5   3     Rad  75.25     21