当前位置: 首页 > 知识库问答 >
问题:

用dict、preserve和NaNs重新映射pandas列中的值

苗烈
2023-03-14

我有一个字典,看起来像这样: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生成列的链接,反之亦然:-/

共有3个答案

王俊楚
2023-03-14

你的问题有点模棱两可。至少有

  1. di中的键引用索引值
  2. di中的键引用df['col1']
  3. 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

我已经修改了您原始帖子中的值,以便更清楚地了解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    A   30
0    B  NaN

注意在这种情况下,di中的键是如何更改的,以匹配df['col1']中的值。

案例3:如果di中的键指的是索引位置,那么您可以使用

df['col1'].put(di.keys(), di.values())

自从

df = pd.DataFrame({'col1':['w', 10, 20],
                   'col2': ['a', 30, np.nan]},
                  index=[1,2,0])
di = {0: "A", 2: "B"}

# The values at the 0 and 2 index locations are replaced by 'A' and 'B'
df['col1'].put(di.keys(), di.values())
print(df)

产量

  col1 col2
1    A    a
2   10   30
0    B  NaN

在这里,第一行和第三行被更改,因为di中的键是02,它们与Python基于0的索引一起引用第一和第三个位置。

鄂育
2023-03-14

如果您的词典有多个键,那么使用mapreplace快得多。此方法有两种版本,具体取决于您的字典是否详尽地映射了所有可能的值(以及是否希望非匹配项保留其值或转换为NAN):

在这种情况下,形式非常简单:

df['col1'].map(di)       # note: if the dictionary does not exhaustively map all
                         # entries then non-matched entries are changed to NaNs

虽然map通常以函数作为参数,但它也可以选择字典或系列: Documation for Pandas.series.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的速度大约是替换的10倍。

请注意,您的map加速将随您的数据而变化。最大的加速似乎是大字典和详尽的替换。有关更广泛的基准测试和讨论,请参见@jpp回答(上面链接)。

夏锐藻
2023-03-14

您可以使用。更换。例如:

>>> 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

或者直接在Series上,即df["col1"]。替换(di, inplace=True)

 类似资料:
  • 问题内容: 我有一本字典,看起来像这样: 我想将其应用于类似于以下内容的数据框的列: 我怎样才能最好地做到这一点?出于某种原因,与此相关的谷歌搜索术语仅向我显示了有关如何根据字典创建列的链接,反之亦然 问题答案: 你可以使用。例如: 或直接在上,即。

  • 问题内容: 我正在开发一个程序(除其他外),其中读取CSV文件(将它存储为dict形式的数组)。对于每一行,作为其他处理的一部分,我需要将这些键重新映射到用户输入的值,这些值在另一个dict中提供,以便可以在API调用中用作参数。映射数组的形式为: 。 所以我想从: 我想使用类似(尽管yields )的东西。 似乎应该有一个明显的解决方案暗示我。 如果数据在并且映射在: 我已经接近了,但是它仅在已

  • 我有一个类似的例子,类似于我的另一个问题Pandas:在多个列上使用字典映射列,但是现在,我想不直接使用列“category”的max()值,而是间接使用它来填充第四列“category_name”中的None与问题1中的情况相同,但是增加了一个包含字符串的列。 此处“类别”列始终是填充的,而“类别名称”列有一些缺失值: 我想再一次用值填充无/南,我想使用的逻辑是:使用列“类别”中最大值的行的列“

  • 我有一个数据帧,其中一列中具有值。我想将此 值替换为其他列的相同组合的“类别”的最大值。 示例:熊猫数据帧 我想将3中的值替换为唯一组合(1.2列组)此列的max()值。预期结果如下所示: 我尝试过的:我把1。2.列(“公司产品”)获取3的最大值()。列建立一个字典'类别'。(基于GroupBy结果到列表字典的思想) 我得到这个判决(显示每个组合的最大类别值): 现在我想用字典中每个组合的最大值替

  • 问题内容: 特定实体存在映射例外。不能弄清楚问题出在哪里。我从头到尾检查了所有映射3次。我仍然收到映射异常。 发送给员工的电子邮件仅映射一次。但它仍然报告错误重复映射 错误是: 电子邮件Pojo email.hbm.xml 相关脚本 发送给员工的电子邮件仅映射一次。但它仍然报告错误重复映射 问题答案: 您是否将Employee中的集合设置为逆?

  • 问题内容: 我有一个熊pandas据框,其中有一列我想zscore归一化的实数值: 问题在于,单个值将构成所有数组: 将(或不是scipy的等效功能)应用于pandas数据框的列并使其忽略值的正确方法是什么?我希望它与原始列具有相同的尺寸,并且具有无法归一化的值 编辑 :也许最好的解决方案是使用和?我不明白为什么为此需要更改自由度: 问题答案: 井的版本和将到手的,所以你可以只计算这样(得到相同S