是否可以在 Pandas 中的 loc 中使用 loc 来替换值?
Is it possible to use a loc inside a loc in Pandas to replace a value?
让我先概述一下我要解决的问题。我试图根据包含“-1”的行中的其他两个值,将值“-1”替换为同一列中的另一个值。为了更清楚,这是一个例子。在下面的数据框中,'owner' 列中有两个缺失值。我想要的是将每个“-1”值替换为 'owner' 列中具有相同 'price' 值且第一个出现在 'time' 之前的值'-1' 值。因此,在这个例子中,第一个 -1
值在第 3 行找到。对应的 'price' 和 'time' 是 cheap
和 2011-01-01 13:30:00
。所以现在,我想用车主的名字替换 -1
,车主有一辆 cheap
车,这是在考虑的车之前的第一时间,所以在 [= 之前的第一次15=]。在这种情况下,那将是第 1 行中的那个,所有者名称为 Jane
。对于以下任何 -1
值(例如 Bmw)也应自动完成此操作。
brand price time owner
0 Honda cheap 2008-01-01 13:30:00 Marc
1 Toyota cheap 2009-01-01 13:30:00 Jane
2 Ford alot 2010-01-01 13:30:00 Phil
3 Audi cheap 2011-01-01 13:30:00 -1
4 Volvo cheap 2012-01-01 13:30:00 Jane
5 Bmw alot 2013-01-01 13:30:00 -1
我想解决这个问题的方法是,先定位到-1,然后保存对应的价格和时间,然后及时定位到第一个对应的价格,替换owner值。我想通过以下方式为此使用 Pandas Loc 方法(我也包含了制作数据框的代码)。
import pandas as pd
from datetime import datetime
cars = {'brand': ['Honda','Toyota','Ford','Audi','Volvo','Bmw'],
'price': ['cheap','cheap','alot','cheap','cheap','alot'],
'time': [datetime.strptime('1/1/2008 1:30 PM', '%m/%d/%Y %I:%M %p'),datetime.strptime('1/1/2009 1:30 PM', '%m/%d/%Y %I:%M %p'),datetime.strptime('1/1/2010 1:30 PM', '%m/%d/%Y %I:%M %p'),datetime.strptime('1/1/2011 1:30 PM', '%m/%d/%Y %I:%M %p'),
datetime.strptime('1/1/2012 1:30 PM', '%m/%d/%Y %I:%M %p'),datetime.strptime('1/1/2013 1:30 PM', '%m/%d/%Y %I:%M %p')],
'owner': ['Marc', 'Jane','Phil','-1','Jane','-1']}
df = pd.DataFrame(cars, columns = ['brand', 'price','time','owner'])
P_T = df.loc[df.owner == '-1',['price','time']
df.loc[df.owner == '-1', 'owner'] = df.loc[(df.price == P_T.price)&(df.time < P_T.time), 'owner']
如您在最后一行中所见,这本质上是一个位置中的位置,而等式右侧的条件均基于 P_T 位置。但是,问题来了,因为我不断收到此错误:
ValueError: Can only compare identically-labeled Series objects
我认为我做错了什么,也许做事的效率不高……所以我真的很感激能在这件事上提供一些帮助。
我认为您把这个问题复杂化了 - 本质上您需要做的是用按价格列分组的最后一个对应值填充 -1
值?如果是这样,前向填充就可以 ffill
import numpy as np
s = df.replace('-1',np.nan).sort_values('time').groupby(['price'])['owner'].ffill()
df['owner'] = df.index.map(s)
print(df)
brand price time owner
0 Honda cheap 2008-01-01 13:30:00 Marc
1 Toyota cheap 2009-01-01 13:30:00 Jane
2 Ford alot 2010-01-01 13:30:00 Phil
3 Audi cheap 2011-01-01 13:30:00 Jane
4 Volvo cheap 2012-01-01 13:30:00 Jane
5 Bmw alot 2013-01-01 13:30:00 Phil
让我先概述一下我要解决的问题。我试图根据包含“-1”的行中的其他两个值,将值“-1”替换为同一列中的另一个值。为了更清楚,这是一个例子。在下面的数据框中,'owner' 列中有两个缺失值。我想要的是将每个“-1”值替换为 'owner' 列中具有相同 'price' 值且第一个出现在 'time' 之前的值'-1' 值。因此,在这个例子中,第一个 -1
值在第 3 行找到。对应的 'price' 和 'time' 是 cheap
和 2011-01-01 13:30:00
。所以现在,我想用车主的名字替换 -1
,车主有一辆 cheap
车,这是在考虑的车之前的第一时间,所以在 [= 之前的第一次15=]。在这种情况下,那将是第 1 行中的那个,所有者名称为 Jane
。对于以下任何 -1
值(例如 Bmw)也应自动完成此操作。
brand price time owner
0 Honda cheap 2008-01-01 13:30:00 Marc
1 Toyota cheap 2009-01-01 13:30:00 Jane
2 Ford alot 2010-01-01 13:30:00 Phil
3 Audi cheap 2011-01-01 13:30:00 -1
4 Volvo cheap 2012-01-01 13:30:00 Jane
5 Bmw alot 2013-01-01 13:30:00 -1
我想解决这个问题的方法是,先定位到-1,然后保存对应的价格和时间,然后及时定位到第一个对应的价格,替换owner值。我想通过以下方式为此使用 Pandas Loc 方法(我也包含了制作数据框的代码)。
import pandas as pd
from datetime import datetime
cars = {'brand': ['Honda','Toyota','Ford','Audi','Volvo','Bmw'],
'price': ['cheap','cheap','alot','cheap','cheap','alot'],
'time': [datetime.strptime('1/1/2008 1:30 PM', '%m/%d/%Y %I:%M %p'),datetime.strptime('1/1/2009 1:30 PM', '%m/%d/%Y %I:%M %p'),datetime.strptime('1/1/2010 1:30 PM', '%m/%d/%Y %I:%M %p'),datetime.strptime('1/1/2011 1:30 PM', '%m/%d/%Y %I:%M %p'),
datetime.strptime('1/1/2012 1:30 PM', '%m/%d/%Y %I:%M %p'),datetime.strptime('1/1/2013 1:30 PM', '%m/%d/%Y %I:%M %p')],
'owner': ['Marc', 'Jane','Phil','-1','Jane','-1']}
df = pd.DataFrame(cars, columns = ['brand', 'price','time','owner'])
P_T = df.loc[df.owner == '-1',['price','time']
df.loc[df.owner == '-1', 'owner'] = df.loc[(df.price == P_T.price)&(df.time < P_T.time), 'owner']
如您在最后一行中所见,这本质上是一个位置中的位置,而等式右侧的条件均基于 P_T 位置。但是,问题来了,因为我不断收到此错误:
ValueError: Can only compare identically-labeled Series objects
我认为我做错了什么,也许做事的效率不高……所以我真的很感激能在这件事上提供一些帮助。
我认为您把这个问题复杂化了 - 本质上您需要做的是用按价格列分组的最后一个对应值填充 -1
值?如果是这样,前向填充就可以 ffill
import numpy as np
s = df.replace('-1',np.nan).sort_values('time').groupby(['price'])['owner'].ffill()
df['owner'] = df.index.map(s)
print(df)
brand price time owner
0 Honda cheap 2008-01-01 13:30:00 Marc
1 Toyota cheap 2009-01-01 13:30:00 Jane
2 Ford alot 2010-01-01 13:30:00 Phil
3 Audi cheap 2011-01-01 13:30:00 Jane
4 Volvo cheap 2012-01-01 13:30:00 Jane
5 Bmw alot 2013-01-01 13:30:00 Phil