替换 pandas DataFrame 中的列值

2025-01-22 08:45:00
admin
原创
90
摘要:问题描述:我正在尝试替换数据框中某一列的值。列 ('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大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1642  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1373  
  信创,即信息技术应用创新产业,旨在实现信息技术领域的自主可控,推动我国数字经济的高质量发展。在金融行业,信创的应用具有极其重要的意义。金融作为国家经济的核心领域,其安全稳定运行关乎国计民生。随着国际形势的变化和信息技术的飞速发展,金融行业对自主创新、安全可靠的信息技术需求愈发迫切。国货国用信创在金融行业的应用,不仅能够...
信创产品有哪些   0  
  信创技术,即信息技术应用创新产业技术,涵盖了从芯片、服务器、操作系统到数据库、中间件等一系列基础软硬件领域。近年来,信创技术发展迅猛,正以前所未有的态势渗透到传统制造业的各个环节,深刻改变着传统制造业的格局。传统制造业长期以来依赖于传统的生产模式、管理方式以及技术架构,在全球经济环境变化、市场竞争加剧的背景下,面临着转...
信创软件有哪些   0  
  信创产业作为近年来备受瞩目的领域,正深刻影响着全球科技格局与经济发展走向。它不仅仅是信息技术的创新应用,更是国家战略安全、产业转型升级的关键支撑。在数字化浪潮席卷而来的当下,信创产业的发展态势成为各界关注焦点。对其未来5年发展趋势进行预测,有助于我们提前布局、把握机遇,在这场科技变革中占据有利位置。技术创新引领产业升级...
国产化信创什么意思   0  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用