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

2024-04-26 23:46:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试图将Stata代码重新编程为Python以提高速度,我被指向PANDAS的方向。然而,我很难理解如何处理数据。

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

在斯塔塔,情况是这样的:

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

不知道从这里去哪里。有什么想法吗?


Tags: csv代码idpandasdfif编程matt
3条回答

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

假设这是您的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])

这个问题可能仍然经常被访问,因此值得为卡西斯的回答提供一个补充。可以对内置类dict进行子类化,以便为“丢失”键返回默认值。这种机制对熊猫很有效。但见下文。

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

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

同样的事情可以通过下面的方式更简单地完成。对dict对象的get方法使用“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         

一种方法是使用Python的切片和索引特性来逻辑地计算条件所在的位置,并覆盖其中的数据。

假设您可以使用pandas.read_csv将数据直接加载到pandas中,那么下面的代码可能对您有所帮助。

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进行覆盖分配操作。


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

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

相关问题 更多 >