Python 使用dict重新映射列中的值
我有一本这样的字典:Python 使用dict重新映射列中的值,python,dictionary,pandas,remap,Python,Dictionary,Pandas,Remap,我有一本这样的字典:di={1:a',2:B} 我想将其应用于数据帧的“col1”列,类似于: col1 col2 0 w a 1 1 2 2 2 NaN 要获得: col1 col2 0 w a 1 A 2 2 B NaN 我怎样才能做到最好?出于某种原因,谷歌搜索与此相关的术语只会向我显示有关如何从dicts生成列的链接,反之亦然:-/你
di={1:a',2:B}
我想将其应用于数据帧的“col1”列,类似于:
col1 col2
0 w a
1 1 2
2 2 NaN
要获得:
col1 col2
0 w a
1 A 2
2 B NaN
我怎样才能做到最好?出于某种原因,谷歌搜索与此相关的术语只会向我显示有关如何从dicts生成列的链接,反之亦然:-/你的问题有点模棱两可。至少有三种和两种解释:
di
中的键指的是索引值di
中的键指的是df['col1']
值di
中的键指的是索引位置(不是OP的问题,而是为了好玩而抛出的。)案例1: 如果
di
的键是指索引值,则可以使用update
方法:
df['col1'].update(pd.Series(di))
比如说,
import pandas as pd
import numpy as np
df = pd.DataFrame({'col1':['w', 10, 20],
'col2': ['a', 30, np.nan]},
index=[1,2,0])
# col1 col2
# 1 w a
# 2 10 30
# 0 20 NaN
di = {0: "A", 2: "B"}
# The value at the 0-index is mapped to 'A', the value at the 2-index is mapped to 'B'
df['col1'].update(pd.Series(di))
print(df)
屈服
col1 col2
1 w a
2 B 30
0 A NaN
col1 col2
1 w a
2 A 30
0 B NaN
col1 col2
1 A a
2 10 30
0 B NaN
我已经修改了您原始帖子中的值,以便更清楚地了解update
正在做什么。
注意di
中的键如何与索引值关联。索引值的顺序——即索引位置——并不重要
案例2: 如果
di
中的键指的是df['col1']
值,则@DanAllan和@DSM说明了如何通过替换实现这一点:
import pandas as pd
import numpy as np
df = pd.DataFrame({'col1':['w', 10, 20],
'col2': ['a', 30, np.nan]},
index=[1,2,0])
print(df)
# col1 col2
# 1 w a
# 2 10 30
# 0 20 NaN
di = {10: "A", 20: "B"}
# The values 10 and 20 are replaced by 'A' and 'B'
df['col1'].replace(di, inplace=True)
print(df)
屈服
col1 col2
1 w a
2 B 30
0 A NaN
col1 col2
1 w a
2 A 30
0 B NaN
col1 col2
1 A a
2 10 30
0 B NaN
注意在这种情况下,di
中的键是如何更改的,以匹配df['col1']
中的值
案例3:
如果di
中的键指向索引位置,则可以使用
df['col1'].put(di.keys(), di.values())
自
屈服
col1 col2
1 w a
2 B 30
0 A NaN
col1 col2
1 w a
2 A 30
0 B NaN
col1 col2
1 A a
2 10 30
0 B NaN
在这里,第一行和第三行被修改了,因为di
中的键是0
和2
,它们与Python基于0的索引一起指向第一和第三个位置。您的问题有点模棱两可。至少有三种和两种解释:
di
中的键指的是索引值
di
中的键指的是df['col1']
值
di
中的键指的是索引位置(不是OP的问题,而是为了好玩而抛出的。)
下面是每种情况的解决方案
案例1:
如果di
的键是指索引值,则可以使用update
方法:
df['col1'].update(pd.Series(di))
比如说,
import pandas as pd
import numpy as np
df = pd.DataFrame({'col1':['w', 10, 20],
'col2': ['a', 30, np.nan]},
index=[1,2,0])
# col1 col2
# 1 w a
# 2 10 30
# 0 20 NaN
di = {0: "A", 2: "B"}
# The value at the 0-index is mapped to 'A', the value at the 2-index is mapped to 'B'
df['col1'].update(pd.Series(di))
print(df)
屈服
col1 col2
1 w a
2 B 30
0 A NaN
col1 col2
1 w a
2 A 30
0 B NaN
col1 col2
1 A a
2 10 30
0 B NaN
我已经修改了您原始帖子中的值,以便更清楚地了解update
正在做什么。
注意di
中的键如何与索引值关联。索引值的顺序——即索引位置——并不重要
案例2:
如果di
中的键指的是df['col1']
值,则@DanAllan和@DSM说明了如何通过替换实现这一点:
import pandas as pd
import numpy as np
df = pd.DataFrame({'col1':['w', 10, 20],
'col2': ['a', 30, np.nan]},
index=[1,2,0])
print(df)
# col1 col2
# 1 w a
# 2 10 30
# 0 20 NaN
di = {10: "A", 20: "B"}
# The values 10 and 20 are replaced by 'A' and 'B'
df['col1'].replace(di, inplace=True)
print(df)
屈服
col1 col2
1 w a
2 B 30
0 A NaN
col1 col2
1 w a
2 A 30
0 B NaN
col1 col2
1 A a
2 10 30
0 B NaN
注意在这种情况下,di
中的键是如何更改的,以匹配df['col1']
中的值
案例3:
如果di
中的键指向索引位置,则可以使用
df['col1'].put(di.keys(), di.values())
自
屈服
col1 col2
1 w a
2 B 30
0 A NaN
col1 col2
1 w a
2 A 30
0 B NaN
col1 col2
1 A a
2 10 30
0 B NaN
在这里,第一行和第三行被更改,因为di
中的键是0
和2
,它们与Python基于0的索引一起引用第一和第三个位置。您可以使用。例如:
>>> df = pd.DataFrame({'col2': {0: 'a', 1: 2, 2: np.nan}, 'col1': {0: 'w', 1: 1, 2: 2}})
>>> di = {1: "A", 2: "B"}
>>> df
col1 col2
0 w a
1 1 2
2 2 NaN
>>> df.replace({"col1": di})
col1 col2
0 w a
1 A 2
2 B NaN
或者直接在上,即df[“col1”]。替换(di,inplace=True)
您可以使用。例如:
>>> df = pd.DataFrame({'col2': {0: 'a', 1: 2, 2: np.nan}, 'col1': {0: 'w', 1: 1, 2: 2}})
>>> di = {1: "A", 2: "B"}
>>> df
col1 col2
0 w a
1 1 2
2 2 NaN
>>> df.replace({"col1": di})
col1 col2
0 w a
1 A 2
2 B NaN
或者直接在地图上,即df[“col1”].replace(di,inplace=True)
map
比replace
快得多
如果您的词典有多个键,那么使用map
比replace
快得多。此方法有两种版本,具体取决于您的字典是否详尽地映射了所有可能的值(以及是否希望非匹配项保留其值或转换为NAN):
穷举映射
在这种情况下,形式非常简单:
df['col1'].map(di) # note: if the dictionary does not exhaustively map all
# entries then non-matched entries are changed to NaNs
虽然map
最常用的参数是函数,但也可以使用字典或系列:
非穷举映射
如果您有一个非穷举映射,并且希望保留非匹配的现有变量,则可以添加fillna
:
df['col1'].map(di).fillna(df['col1'])
正如@jpp在这里的回答:
基准
在0.23.1版中使用以下数据:
di = {1: "A", 2: "B", 3: "C", 4: "D", 5: "E", 6: "F", 7: "G", 8: "H" }
df = pd.DataFrame({ 'col1': np.random.choice( range(1,9), 100000 ) })
使用%timeit
进行测试时,map
似乎比replace
快10倍左右
请注意,map
的加速比将随数据而变化。最大的加速似乎是使用大型词典和详尽的替换。有关更广泛的基准测试和讨论,请参见@jpp-answer(上面链接)。map
比replace
如果您的词典有多个键,那么使用map
比replace
快得多。此方法有两种版本,具体取决于您的字典是否详尽地映射了所有可能的值(以及是否希望非匹配项保留其值或转换为NAN):
穷举映射
在这种情况下,形式非常简单:
df['col1'].map(di) # note: if the dictionary does not exhaustively map all
# entries then non-matched entries are changed to NaNs
虽然map
最常用的参数是函数,但也可以使用字典或系列:
非穷举映射
如果您有一个非穷举映射,并且希望保留非匹配的现有变量,则可以添加fillna
:
df['col1'].map(di).fillna(df['col1'])
正如@jpp在这里的回答:
基准
在0.23.1版中使用以下数据:
di = {1: "A", 2: "B", 3: "C", 4: "D", 5: "E", 6: "F", 7: "G", 8: "H" }
df = pd.DataFrame({ 'col1': np.random.choice( range(1,9), 100000 ) })
使用%timeit
进行测试时,map
似乎比replace
快10倍左右
请注意,map
的加速比将随数据而变化。最大的加速似乎是使用大型词典和详尽的替换。见@jpp答案(链接