Pandas dict 在多个列上的应用,处理不匹配的值
Pandas dict application over several columns, handling non matches values
我有一个像这样的数据框:
ì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)
一样,因为他们return同样的问题:
name addres job
0 0 0 2
1 1 1 E
2 C 2 2
3 0 add4 3
问题是不匹配的值(如 addres
列中的 add4
或 name
列中的 C
或 [=25 列中的 E
=]) 不会被替换为 .replace
函数的任何参数。我需要将这些值映射到 -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
所以,我知道怎么做了,这已经被证明了。
我的问题是:
-
- 我不认为 pandas 是用来遍历列的,而是矢量化函数应用在列上的。
-
- 我的真实数据框足够大,需要矢量化函数,
mapping_dict
也足够大。
所以,如果我可以将 apply
与 axis=1
一起使用,并以某种方式获得列名称 column_name
,就像 pandas.Series.column_name
,我可以做类似的事情:
df[columns].apply(lambda x: mapping_dict[x.column_name].get(x,-1) , axis=1)
到目前为止,我认为继承 class 拥有 pandas.dataframe
所有属性并添加 x.column_name
是“大炮杀死蚊子”的解决方案。
那么你知道任何快速的单行解决方案吗?
在每列的字典末尾添加一个“包罗万象”。这是任何不匹配的东西变成 -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
我有一个像这样的数据框:
ì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)
一样,因为他们return同样的问题:
name addres job
0 0 0 2
1 1 1 E
2 C 2 2
3 0 add4 3
问题是不匹配的值(如 addres
列中的 add4
或 name
列中的 C
或 [=25 列中的 E
=]) 不会被替换为 .replace
函数的任何参数。我需要将这些值映射到 -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)
或更好的
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
所以,我知道怎么做了,这已经被证明了。
我的问题是:
-
- 我不认为 pandas 是用来遍历列的,而是矢量化函数应用在列上的。
-
- 我的真实数据框足够大,需要矢量化函数,
mapping_dict
也足够大。
- 我的真实数据框足够大,需要矢量化函数,
所以,如果我可以将 apply
与 axis=1
一起使用,并以某种方式获得列名称 column_name
,就像 pandas.Series.column_name
,我可以做类似的事情:
df[columns].apply(lambda x: mapping_dict[x.column_name].get(x,-1) , axis=1)
到目前为止,我认为继承 class 拥有 pandas.dataframe
所有属性并添加 x.column_name
是“大炮杀死蚊子”的解决方案。
那么你知道任何快速的单行解决方案吗?
在每列的字典末尾添加一个“包罗万象”。这是任何不匹配的东西变成 -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