Pandas 使用过滤器映射多列

问题描述 投票:0回答:1

我有一个像这样的数据框(针对此示例进行了简化)

 Site     LocationName    Resource#    
   01        Test Name            5
   01          Testing            6
   02       California           10
   02            Texas           11
   ...

每个站点都有自己的

LocationName
Resource#

映射

例如:

  • 站点 01 具有
    {'Test Name': 'Another Test', 'Testing': 'RandomLocation'}
    的映射
    LocationName
    以及
    {5: 5000}
    Resource#
  • 映射
  • 站点 02 具有
    {'California': 'CA-123'}
    LocationName
    映射以及
    {10: '10A', 11: '11B'}
    Resource#
  • 映射

我正在尝试使用不同列的映射来映射每个相应的站点。如果映射不存在,我希望该字段为无/空白。

我理想的输出是:

Site#     LocationName    Resource#    
   01     Another Test         5000
   01   RandomLocation
   02           CA-123          10A
   02                           11B

我的想法是过滤每个站点并在系列上运行地图

df01 = df[df.Site == '01']
df01 = df['LocationName'].map({'Test Name': 'Another Test', 'Testing': 'RandomLocation'})

但是这会返回

SettingWithCopyWarning
,因为我正在副本上执行这些操作。

有没有简单的方法可以实现这一点?

python pandas dictionary pandas-settingwithcopy-warning
1个回答
0
投票

是的,有。您可以在数据帧的

map
方法中使用
apply
函数。

import pandas as pd

data = {
    'Site': ['01', '01', '02', '02'],
    'LocationName': ['Test Name', 'Testing', 'California', 'Texas'],
    'Resource#': [5, 6, 10, 11]
}

df = pd.DataFrame(data)

mappings = {
    '01': {
        'LocationName': {'Test Name': 'Another Test', 'Testing': 'RandomLocation'},
        'Resource#': {5: '5000', 6: None}  
    },
    '02': {
        'LocationName': {'California': 'CA-123', 'Texas': None},
        'Resource#': {10: '10A', 11: '11B'}
    }
}

def apply_mappings(row):
    site = row['Site']
    if site in mappings:
        location_map = mappings[site]['LocationName']
        row['LocationName'] = location_map.get(row['LocationName'])

        resource_map = mappings[site]['Resource#']
        row['Resource#'] = resource_map.get(row['Resource#'], None)  
    return row

df = df.apply(apply_mappings, axis=1)

print(df)

这将为您提供预期的输出:

  Site    LocationName Resource#
0   01    Another Test      5000
1   01  RandomLocation      None
2   02          CA-123       10A
3   02            None       11B
© www.soinside.com 2019 - 2024. All rights reserved.