我想修改以下数据帧df:的col1
col1 col2
0 Black 7
1 Death 2
2 Hardcore 6
3 Grindcore 1
4 Deathcore 4
...
我想使用一个名为cat_dic={'Black':'B', 'Death':'D', 'Hardcore':'H'}
的dict来获得以下数据帧:
col1 col2
0 B 7
1 D 2
2 H 6
3 None 1
4 None 4
...
我知道我可以使用df.map
或df.replace
,例如:
df.replace({"col1":cat_dic})
但是我希望dictionary的KeyErrors返回None,在前一行中,我得到了以下结果:
col1 col2
0 B 7
1 D 2
2 H 6
3 Grindcore 1
4 Deathcore 4
...
考虑到Grindcore和Deathcore并不是col1中唯一两个我想设置为None的值,你知道怎么做吗?
使用dict.get
:
df['col1'] = df['col1'].map(lambda x: cat_dic.get(x, None))
#default value is None
df['col1'] = df['col1'].map(cat_dic.get)
print (df)
col1 col2
0 B 7
1 D 2
2 H 6
3 None 1
4 None 4
50k行的性能比较:
df = pd.concat([df] * 10000, ignore_index=True)
cat_dic={'Black':'B', 'Death':'D', 'Hardcore':'H'}
In [93]: %timeit df['col1'].map(cat_dic.get)
3.22 ms ± 16.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [94]: %timeit df.col1.apply(lambda x: None if x not in cat_dic.keys() else cat_dic[x])
15 ms ± 293 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [95]: %timeit df['col1'].replace(dict(dict.fromkeys(df['col1'].unique(), None), **cat_dic))
12.3 ms ± 409 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [96]: %timeit df.col1.apply(lambda x: None if x not in cat_dic.keys() else x)
13.8 ms ± 837 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [97]: %timeit df['col1'].map(cat_dic).replace(dict({np.nan: None}))
9.97 ms ± 1.25 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
您可以首先使用pd.apply
df.col1 = df.col1.apply(lambda x: None if x not in cat_dic.keys() else x)
然后,您可以安全地使用pd.replace
df.replace({"col1":cat_dic})
这可以在一行中完成:
df1['col1'] = df1.col1.apply(lambda x: None if x not in cat_dic.keys() else cat_dic[x])
输出为:
col1 col2
0 B 7
1 D 2
2 H 6
3 None 1
4 None 4
这里有一个简单的一行解决方案,它为我们提供了预期的输出。
df['col1'] = df['col1'].map(cat_dic).replace(dict({np.nan: None}))
输出:
col1 col2
0 B 7
1 D 2
2 H 6
3 None 1
4 None 4
Series.map
已经将NaN
映射到不匹配的密钥
$ print(df['col1'].map(cat_dic))
0 B
1 D
2 H
3 NaN
4 NaN
Name: col1, dtype: object
无论如何,您可以使用col1
列中丢失的密钥更新cat_dic
cat_dic = dict(dict.fromkeys(df['col1'].unique(), None), **cat_dic)
df['col1'] = df['col1'].replace(cat_dic)
print(cat_dic)
{'Black': 'B', 'Death': 'D', 'Hardcore': 'H', 'Grindcore': None, 'Deathcore': None}
print(df)
col1 col2
0 B 7
1 D 2
2 H 6
3 None 1
4 None 4
In [6]: df.col1.map(cat_dic.get)
Out[6]:
0 B
1 D
2 H
3 None
4 None
dtype: object
您也可以使用apply
,两者都有效。当使用Series
时,我认为map
更快。
说明:
您可以通过使用dict.get
而不是使用[..]
-运算符来获得丢失密钥的默认值。默认情况下,此默认值为None
。因此,简单地将dict.get
方法传递给apply
/map
就可以了。