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

根据 pandas 中的另一个值更改一个值

麹培
2023-03-14

我试图用Python复制我的Stata代码,我被指向熊猫的方向。然而,我很难思考如何处理数据

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

在Stata,它看起来像这样:

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

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

在熊猫身上,我正在尝试这样的东西

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

不知道该何去何从。有什么想法吗?

共有3个答案

裴曜灿
2023-03-14

最初的问题解决了一个特定的狭窄用例。对于那些需要更通用答案的人,这里有一些例子:

给定以下数据帧:

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

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

df['description'] = 'A ' + df.age.astype(str) + ' years old ' \
                    + 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年(而不是1年),我们将在下面使用条件进行修复。

这里,我们用其他列中的值替换原来的< code>animal列,并使用< code>np.where根据< code>age的值设置条件子字符串:

# append 's' to 'age' if it's greater than 1
df.animal = df.animal + ", " + df.type + ", " + \
    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

df.apply(transform_row, axis=1)

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

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

谢鸿
2023-03-14

您可以使用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])
欧阳俊晖
2023-03-14

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

假设您可以使用pandas将数据直接加载到pandas中。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'

请注意,您需要 pandas 版本 0.11 或更高版本才能使用 loc 进行覆盖分配操作。

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

import pandas
df = pandas.read_csv("test.csv")
df['FirstName'][df.ID == 103] = "Matt"
df['LastName'][df.ID == 103] = "Jones"
 类似资料:
  • 问题内容: 我需要基于Pandas数据框中的另一列的值来设置一列的值。这是逻辑: 我无法做到这一点,我想要做的就是简单地创建一个具有新值的列(或更改现有列的值:任何一个都对我有用)。 如果我尝试运行上面的代码,或者将其编写为函数并使用apply方法,则会得到以下信息: 问题答案: 一种方法是将索引与配合使用。 例 在没有示例数据框的情况下,我将在此处进行补充: 假设您想 创建一个新列 ,除wher

  • 我对谷歌表单和电子表格非常陌生,我想做的是,我的表单中有一个“年龄”问题,当用户提交表单时,我想要它,这样,如果年龄低于18岁,一个单元格就会得到值“MINOR”,如果是18岁或以上,就会用“MAJOR”填充。 基本上,我想根据“AGE”的值动态地为这个单元格添加一个值。 我现在正在做的是: 其中,是值次要/主要的单元格。

  • 问题内容: 我有一个名为Vendor的表,在此表中有一个名为AccountTerms的列,该列仅显示一个值(即0、1、2、3),依此类推。我也有一个要使用()的列,以反映该值的含义,例如: 等等… 我需要的是一个脚本,它将查看AccountTerms中的值,然后将更新以显示上面显示的单词值。我该怎么做呢? 问题答案: 我将尝试以一种尽可能简单的方式来解释这一点,以便于理解: 假设您有一个这样的表设

  • 问题内容: 在Mysql中: 我表中的城市有重复的值: 座席城市: 该表中的数据格式为: 与…一样: 表国家: 我想知道每个国家有多少座城市。喜欢: 因此,我有2个查询: 但是此值应来自: 现在,如何获得所需的表? 问题答案: 带有: 结果:

  • 问题内容: 我在SQLite中有两个表,看起来像这样 我试图编写查询以基于表Y中的记录更新表X上的记录。更新的条件如下所示 但是当我尝试这样做时,我收到一条错误消息,说 没有这样的列:table_y.c2 问题答案: 删除的答案关于错误的原因是正确的:必须在查询中 引入 关系标识符(例如,使用FROM / JOIN),然后才能使用它。 虽然SQLite的不 不 支持(因此没有办法直接引入查找关系)