我试图用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:
...
不知道该何去何从。有什么想法吗?
最初的问题解决了一个特定的狭窄用例。对于那些需要更通用答案的人,这里有一些例子:
给定以下数据帧:
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对象)。这简化了处理,因为您可以使用列名访问行中的实际“原始”值,并且可以看到给定行/列中的其他单元格。
您可以使用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])
一种选择是使用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的不 不 支持(因此没有办法直接引入查找关系)