【问题标题】:Pandas dict application over several columns, handling non matches valuesPandas dict 应用多列,处理非匹配值
【发布时间】:2021-02-28 05:32:00
【问题描述】:

我有一个像这样的数据框:

ìmport pandas as pd
df = pd.DataFrame({
       "age" : [20,22,20,23],
       "name" : ["A","B","C","A"],
       "addres" : ["add1","add2","add3","add4"],
       "job" :  ["C","E","C","D"],
       "score" : [0.44,0.43,0.25,0.36]
     })
categors = ["name","addres","job"]
df:

       age name addres job  score
    0   20    A   add1   C   0.44
    1   22    B   add2   E   0.43
    2   20    C   add3   C   0.25
    3   23    A   add4   D   0.36

我有一个这样的字典:

mapping_dict = {
    "name" : {"A":0, "B": 1},
    "addres" : {"add1": 0, "add2": 1, "add3":2},
    "job" : {"A":0, "B":1, "C": 2, "D":3}
    }

我想将此字典应用到他们的匹配列,所以我可以这样做:

df[categors].replace(mapping_dict,inplace=True)

df[categors] = df[categors].replace(mapping_dict)

这是相同的,因为它们返回相同的问题:

      name addres job
    0    0      0   2
    1    1      1   E
    2    C      2   2
    3    0   add4   3

问题是不匹配的值(如addres 列中的add4name 列中的Cjob 列中的E)未被处理为替换为@ 的任何参数987654333@ 功能。我需要将这些值映射到-1

所以,为了实现这一点,我们可以做一个循环:

for column in categors:
    df[column] = df[column].map(mapping_dict[column])

df
   age  name  addres  job  score
0   20   0.0     0.0  2.0   0.44
1   22   1.0     1.0  NaN   0.43
2   20   NaN     2.0  2.0   0.25
3   23   0.0     NaN  3.0   0.36 

并使用.fillna(-1) 或更好的解决NaN

 for column in categors:
     l = lambda x: mapping_dict[column].get(x,-1)
     df[column] = df[column].apply(l)
 df 
        age  name  addres  job  score
    0   20     0       0    2   0.44
    1   22     1       1   -1   0.43
    2   20    -1       2    2   0.25
    3   23     0      -1    3   0.36

所以,我知道该怎么做,这已经被证明了。

我的问题是:

    1. 我不认为 pandas 是用来循环列的,而是在列上应用矢量化函数。
    1. 我的真实数据框足够大,需要矢量化函数,mapping_dict 也足够大。

所以,如果我可以将applyaxis=1 一起使用,并以某种方式像pandas.Series.column_name 一样获得列名column_name,我可以这样做:

df[columns].apply(lambda x: mapping_dict[x.column_name].get(x,-1) , axis=1)

到目前为止,我认为拥有pandas.dataframe 的所有属性并添加x.column_name 的继承类是“大炮杀死蚊子”的解决方案。

那么您知道任何快速、单行解决方案吗?

【问题讨论】:

    标签: python-3.x pandas dictionary apply


    【解决方案1】:

    在每列的字典末尾添加一个“catch-all”。这是任何不匹配的东西变成-1

    mapping_dict = {
        "name" : {"A":0, "B": 1, ".*":-1},
        "addres" : {"add1": 0, "add2": 1, "add3":2, ".*":-1},
        "job" : {"A":0, "B":1, "C": 2, "D":3, ".*":-1}
    }
        
    

    然后只需在替换中包含regex 参数。

    df.replace(mapping_dict, inplace=True, regex=True)
    
       age  name  addres  job  score
    0   20     0       0    2   0.44
    1   22     1       1   -1   0.43
    2   20    -1       2    2   0.25
    3   23     0      -1    3   0.36
    

    【讨论】:

    • 所以,我需要在整个字典 mapping_dict 上进行多次插入。哼一些快速的代码?
    • 如果您担心添加,".*":-1 所需的时间,只需使用简单的正则表达式或在文本编辑器中查找/替换即可。全部}变成,".*":-1 }
    • 不,我只是更聪明地解决它。这是一个预测函数(将分类数据更改为数字数据),因此在我的预处理部分中,我使用categors_dict = dict() 保存和初始化字典。现在我只是将这一行改为categors_dict= {".*":-1}
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-12
    • 2023-01-10
    • 2021-10-06
    • 2020-11-04
    • 1970-01-01
    相关资源
    最近更新 更多