根据熊猫中的另一个值更改一个值

2025-01-16 08:38:00
admin
原创
166
摘要:问题描述:我正在尝试用 Python 重现我的 Stata 代码,并且我被指向 Pandas。然而,我很难理解如何处理数据。假设我想迭代列标题“ID”中的所有值。如果该 ID 与特定数字匹配,那么我想更改两个相应的值 FirstName 和 LastName。在 Stata 中它看起来像这样:replace ...

问题描述:

我正在尝试用 Python 重现我的 Stata 代码,并且我被指向 Pandas。然而,我很难理解如何处理数据。

假设我想迭代列标题“ID”中的所有值。如果该 ID 与特定数字匹配,那么我想更改两个相应的值 FirstName 和 LastName。

在 Stata 中它看起来像这样:

replace FirstName = "Matt" if ID==103
replace LastName =  "Jones" if ID==103

因此,这将把 FirstName 中与 ID == 103 的值相对应的所有值替换为 Matt。

在 Pandas 中,我正在尝试这样的事情

df = read_csv("test.csv")
for i in df['ID']:
    if i ==103:
          ...

不知道接下来该去哪里。有什么想法吗?


解决方案 1:

一种选择是使用 Python 的切片和索引功能来逻辑地评估条件所在的位置并在那里覆盖数据。

假设您可以直接加载数据pandaspandas.read_csv那么以下代码可能会对您有所帮助。

import pandas
df = pandas.read_csv("test.csv")
df.loc[df.ID == 103, 'FirstName'] = "Matt"
df.loc[df.ID == 103, 'LastName'] = "Jones"

正如评论中提到的,您还可以一次性对两列进行分配:

df.loc[df.ID == 103, ['FirstName', 'LastName']] = 'Matt', 'Jones'

请注意,您需要pandas0.11 或更新版本才能使用loc覆盖赋值操作。事实上,对于像 0.8 这样的旧版本(尽管链式赋值批评者可能会说),链式赋值是正确的方法,因此了解在更新版本的 pandas 中是否应该避免使用链式赋值是有用的。


另一种方法是使用所谓的链式赋值。这种方法不太稳定,因此不被认为是最佳解决方案(文档中明确不鼓励这样做),但了解以下内容很有用:

import pandas
df = pandas.read_csv("test.csv")
df['FirstName'][df.ID == 103] = "Matt"
df['LastName'][df.ID == 103] = "Jones"

解决方案 2:

您可以使用map,它可以映射来自字典甚至自定义函数的值。

假设这是你的 df:

    ID First_Name Last_Name
0  103          a         b
1  104          c         d

创建字典:

fnames = {103: "Matt", 104: "Mr"}
lnames = {103: "Jones", 104: "X"}

和地图:

df['First_Name'] = df['ID'].map(fnames)
df['Last_Name'] = df['ID'].map(lnames)

其结果将是:

    ID First_Name Last_Name
0  103       Matt     Jones
1  104         Mr         X

或者使用自定义函数:

names = {103: ("Matt", "Jones"), 104: ("Mr", "X")}
df['First_Name'] = df['ID'].map(lambda x: names[x][0])

解决方案 3:

原始问题针对的是特定的狭窄用例。对于那些需要更多通用答案的人,这里有一些示例:

使用其他列的数据创建新列

鉴于以下数据框:

import pandas as pd
import numpy as np

df = pd.DataFrame([['dog', 'hound', 5],
                   ['cat', 'ragdoll', 1]],
                  columns=['animal', 'type', 'age'])

In[1]:
Out[1]:
  animal     type  age
----------------------
0    dog    hound    5
1    cat  ragdoll    1

下面我们将使用被系列覆盖的操作添加一个新description列作为其他列的串联+。花哨的字符串格式、f 字符串等在这里不起作用,因为它们+适用于标量而不是“原始”值:

df['description'] = 'A ' + df.age.astype(str) + ' years old ' \n                    + df.type + ' ' + df.animal

In [2]: df
Out[2]:
  animal     type  age                description
-------------------------------------------------
0    dog    hound    5    A 5 years old hound dog
1    cat  ragdoll    1  A 1 years old ragdoll cat

我们得到1 years了猫(而不是1 year),我们将在下面使用条件进行修复。

使用条件修改现有列

animal在这里,我们用其他列的值替换原始列,并np.where根据值设置条件子字符串age

# append 's' to 'age' if it's greater than 1
df.animal = df.animal + ", " + df.type + ", " + \n    df.age.astype(str) + " year" + np.where(df.age > 1, 's', '')

In [3]: df
Out[3]:
                 animal     type  age
-------------------------------------
0   dog, hound, 5 years    hound    5
1  cat, ragdoll, 1 year  ragdoll    1

使用条件修改多列

一种更灵活的方法(也可能更慢,请参阅下面的性能)是调用.apply()整个数据框而不是单个列:

def transform_row(r):
    r.animal = 'wild ' + r.type
    r.type = r.animal + ' creature'
    r.age = "{} year{}".format(r.age, r.age > 1 and 's' or '')
    return r

df2 = df.apply(transform_row, axis=1)
print(df2)

In[4]:
Out[4]:
         animal            type      age
----------------------------------------
0    wild hound    dog creature  5 years
1  wild ragdoll    cat creature   1 year

在上面的代码中,transform_row(r)函数采用一个Series表示给定行的对象(用 表示axis=1, 的默认值axis=0将为每一列提供一个Series对象)。这简化了处理,因为您可以使用列名访问行中的实际“原始”值,并且可以查看给定行/列中的其他单元格。

表现

如果性能至关重要,那么您可能想知道使用性能所付出的代价.apply()以及可能的缓解方法:

解决方案 4:

这个问题可能仍然会被经常提及,因此值得为 Kassies 先生的答案提供补充。dict内置类可以进行子类化,以便为“缺失”键返回默认值。这种机制对 pandas 很有效。但请参见下文。

这样就可以避免关键错误。

>>> import pandas as pd
>>> data = { 'ID': [ 101, 201, 301, 401 ] }
>>> df = pd.DataFrame(data)
>>> class SurnameMap(dict):
...     def __missing__(self, key):
...         return ''
...     
>>> surnamemap = SurnameMap()
>>> surnamemap[101] = 'Mohanty'
>>> surnamemap[301] = 'Drake'
>>> df['Surname'] = df['ID'].apply(lambda x: surnamemap[x])
>>> df
    ID  Surname
0  101  Mohanty
1  201         
2  301    Drake
3  401         

用下面的方法可以更简单地完成相同的事情。使用getdict 对象方法的 'default' 参数使得无需对 dict 进行子类化。

>>> import pandas as pd
>>> data = { 'ID': [ 101, 201, 301, 401 ] }
>>> df = pd.DataFrame(data)
>>> surnamemap = {}
>>> surnamemap[101] = 'Mohanty'
>>> surnamemap[301] = 'Drake'
>>> df['Surname'] = df['ID'].apply(lambda x: surnamemap.get(x, ''))
>>> df
    ID  Surname
0  101  Mohanty
1  201         
2  301    Drake
3  401         

解决方案 5:

df['FirstName']=df['ID'].apply(lambda x: 'Matt' if x==103 else '')
df['LastName']=df['ID'].apply(lambda x: 'Jones' if x==103 else '')

解决方案 6:

如果有人正在寻找一种方法来根据每行本身的某些逻辑条件来改变多行的值,那么使用.apply()函数是可行的方法。

df = pd.DataFrame({'col_a':[0,0], 'col_b':[1,2]})

   col_a  col_b
0      0      1
1      0      2

def func(row):
    if row.col_a == 0 and row.col_b <= 1:
        row.col_a = -1
        row.col_b = -1
    return row

df.apply(func, axis=1)

   col_a  col_b
0     -1     -1 # Modified row
1      0      2

虽然.apply()通常用于向数据框添加新行/列,但它可用于修改现有行/列的值。

解决方案 7:

我发现通过打印出每行满足条件的位置来首次亮相要容易得多:

for n in df.columns:
    if(np.where(df[n] == 103)):
        print(n)
        print(df[df[n] == 103].index)
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3892  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2717  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   52  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   54  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   49  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用