替换 pandas DataFrame 中的列值

2025-01-22 08:45:00
admin
原创
85
摘要:问题描述:我正在尝试替换数据框中某一列的值。列 ('female') 仅包含值 'female' 和 'male'。我尝试了以下方法:w['female']['female']='1' w['female']['male']='0' 但收到与以前的结果完全相同的副本。我理想情况下希望获得一些类似于以下循环元...

问题描述:

我正在尝试替换数据框中某一列的值。列 ('female') 仅包含值 'female' 和 'male'。

我尝试了以下方法:

w['female']['female']='1'
w['female']['male']='0' 

但收到与以前的结果完全相同的副本。

我理想情况下希望获得一些类似于以下循环元素的输出。

if w['female'] =='female':
    w['female'] = '1';
else:
    w['female'] = '0';

我已经查看了 gotchas 文档(http://pandas.pydata.org/pandas-docs/stable/gotchas.html),但不明白为什么什么都没有发生。

任何帮助都将受到感谢。


解决方案 1:

如果我理解正确的话,你想要的是这样的:

w['female'] = w['female'].map({'female': 1, 'male': 0})

(在这里,我将值转换为数字,而不是包含数字的字符串。如果您确实愿意,您可以将它们转换为"1""0",但我不确定您为什么要这样做。)

您的代码不起作用的原因是,['female']在列('female'您的中的第二列w['female']['female'])上使用并不意味着“选择值为‘female’的行”。它的意思是选择索引为 female’的行,而您的 DataFrame 中可能没有任何这样的行。

解决方案 2:

您可以使用 loc 编辑数据框的子集:

df.loc[<row selection>, <column selection>]

在这种情况下:

w.loc[w.female != 'female', 'female'] = 0
w.loc[w.female == 'female', 'female'] = 1

解决方案 3:

w.female.replace(to_replace=dict(female=1, male=0), inplace=True)

参见pandas.DataFrame.replace() 文档。

解决方案 4:

稍有变化:

w.female.replace(['male', 'female'], [1, 0], inplace=True)

解决方案 5:

这也应该有效:

w.female[w.female == 'female'] = 1 
w.female[w.female == 'male']   = 0

解决方案 6:

这非常紧凑:

w['female'][w['female'] == 'female']=1
w['female'][w['female'] == 'male']=0

另一个好例子:

w['female'] = w['female'].replace(regex='female', value=1)
w['female'] = w['female'].replace(regex='male', value=0)

解决方案 7:

您也可以apply使用.getie

w['female'] = w['female'].apply({'male':0, 'female':1}.get)

w = pd.DataFrame({'female':['female','male','female']})
print(w)

数据框w

   female
0  female
1    male
2  female

使用apply字典中的替换值:

w['female'] = w['female'].apply({'male':0, 'female':1}.get)
print(w)

结果:

   female
0       1
1       0
2       1 

注意: apply如果数据框中列的所有可能值都在字典中定义,则应使用字典,否则,对于字典中未定义的值,它将为空。

解决方案 8:

w.replace({'female':{'female':1, 'male':0}}, inplace = True)

上述代码将用 1 替换“女性”,用 0 替换“男性”,仅在“女性”列中

解决方案 9:

使用Series.mapSeries.fillna

如果您的列包含的字符串多于femalemale,则Series.map在这种情况下将会失败,因为它将返回NaN其他值。

这就是为什么我们必须用以下方式链接它fillna

.map失败原因示例

df = pd.DataFrame({'female':['male', 'female', 'female', 'male', 'other', 'other']})

   female
0    male
1  female
2  female
3    male
4   other
5   other
df['female'].map({'female': '1', 'male': '0'})

0      0
1      1
2      1
3      0
4    NaN
5    NaN
Name: female, dtype: object

对于正确的方法,我们map用链接fillna,因此我们NaN用原始列中的值填充:

df['female'].map({'female': '1', 'male': '0'}).fillna(df['female'])

0        0
1        1
2        1
3        0
4    other
5    other
Name: female, dtype: object

解决方案 10:

另外,对于这些类型的作业,还有一个内置函数 pd.get_dummies:

w['female'] = pd.get_dummies(w['female'],drop_first = True)

这将为您提供一个包含两列的数据框,每列对应 w['female'] 中出现的一个值,其中删除第一列(因为您可以从剩下的值推断出它)。新列将自动命名为您替换的字符串。

如果您的分类变量具有两个以上的可能值,则这尤其有用。此函数会创建尽可能多的虚拟变量来区分所有情况。请注意不要将整个数据框分配给单个列,而是如果 w['female'] 可以是“male”、“female”或“neutral”,请执行以下操作:

w = pd.concat([w, pd.get_dummies(w['female'], drop_first = True)], axis = 1])
w.drop('female', axis = 1, inplace = True)

然后,您将剩下两个新列,为您提供“女性”的虚拟编码,并且您摆脱了带有字符串的列。

解决方案 11:

pandas中还有一个函数factorize,您可以使用它来自动完成此类工作。它将标签转换为数字:['male', 'female', 'male'] -> [0, 1, 0]。有关更多信息,请参阅此答案。

解决方案 12:

w.female = np.where(w.female=='female', 1, 0)

如果有人正在寻找 numpy 解决方案。这对于根据条件替换值很有用。 if 和 else 条件都是 所固有的np.where()。如果列除了 之外还包含许多唯一值,则使用的解决方案df.replace()可能不可行'male',所有这些都应替换为0

另一个解决方案是连续使用df.where()and df.mask()。这是因为它们都没有实现 else 条件。

w.female.where(w.female=='female', 0, inplace=True) # replace where condition is False
w.female.mask(w.female=='female', 1, inplace=True) # replace where condition is True

解决方案 13:

dic = {'female':1, 'male':0}
w['female'] = w['female'].replace(dic)

.replace 有一个字典作为参数,您可以在其中进行任何您想要或需要的更改。

解决方案 14:

我认为,答案应该指出在上面建议的所有方法中你得到哪种类型的对象:是Series还是DataFrame。

w.female.当您通过或获取列w[[2]](假设 2 是列数)时,您将返回 DataFrame。因此在这种情况下,您可以使用 DataFrame 方法,例如.replace

当您使用.loc或 时,iloc您将返回 Series,而 Series 没有.replace方法,因此您应该使用诸如applymap方法。

解决方案 15:

为了更通用地回答这个问题,使其适用于更多用例,而不仅仅是 OP 所问的,请考虑这个解决方案。我使用了jfs 的解决方案来帮助我。在这里,我们创建了两个互相帮助的函数,无论您是否知道确切的替换方法,都可以使用它们。

import numpy as np
import pandas as pd


class Utility:

    @staticmethod
    def rename_values_in_column(column: pd.Series, name_changes: dict = None) -> pd.Series:
        """
        Renames the distinct names in a column. If no dictionary is provided for the exact name changes, it will default
        to <column_name>_count. Ex. female_1, female_2, etc.

        :param column: The column in your dataframe you would like to alter.
        :param name_changes: A dictionary of the old values to the new values you would like to change.
        Ex. {1234: "User A"} This would change all occurrences of 1234 to the string "User A" and leave the other values as they were.
        By default, this is an empty dictionary.
        :return: The same column with the replaced values
        """
        name_changes = name_changes if name_changes else {}
        new_column = column.replace(to_replace=name_changes)
        return new_column

    @staticmethod
    def create_unique_values_for_column(column: pd.Series, except_values: list = None) -> dict:
        """
        Creates a dictionary where the key is the existing column item and the value is the new item to replace it.
        The returned dictionary can then be passed the pandas rename function to rename all the distinct values in a
        column.
        Ex. column ["statement"]["I", "am", "old"] would return
        {"I": "statement_1", "am": "statement_2", "old": "statement_3"}

        If you would like a value to remain the same, enter the values you would like to stay in the except_values.
        Ex. except_values = ["I", "am"]
        column ["statement"]["I", "am", "old"] would return
        {"old", "statement_3"}

        :param column: A pandas Series for the column with the values to replace.
        :param except_values: A list of values you do not want to have changed.
        :return: A dictionary that maps the old values their respective new values.
        """
        except_values = except_values if except_values else []
        column_name = column.name
        distinct_values = np.unique(column)
        name_mappings = {}
        count = 1
        for value in distinct_values:
            if value not in except_values:
                name_mappings[value] = f"{column_name}_{count}"
                count += 1
        return name_mappings

对于 OP 的用例来说,只需使用就足够简单了

w["female"] = Utility.rename_values_in_column(w["female"], name_changes = {"female": 0, "male":1}

但是,要知道数据框中所有可能需要重命名的不同唯一值并不总是那么容易。在我的例子中,列的字符串值是散列值,因此它们会损害可读性。我所做的是利用该函数将这些散列值替换为更易读的字符串create_unique_values_for_column

df["user"] = Utility.rename_values_in_column(
    df["user"],
    Utility.create_unique_values_for_column(df["user"])
)

这会将我的用户列值从 更改为["1a2b3c", "a12b3c","1a2b3c"]["user_1", "user_2", "user_1]这样比较起来容易多了,对吧?

解决方案 16:

如果只有两个类,则可以使用相等运算符。例如:

df = pd.DataFrame({'col1':['a', 'a', 'a', 'b']})

df['col1'].eq('a').astype(int)
# (df['col1'] == 'a').astype(int)

输出:

0    1
1    1
2    1
3    0
Name: col1, dtype: int64
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用