使用其他数据框和系列快速替换 pandas 数据框的信息
Quickly replacing information of a pandas dataframe using other dataframe and series
我目前正在尝试使用另一个 DataFrame 和一系列用于我的模拟分析来替换 DataFrame 的信息。
玩具示例如下
A为用户信息DataFrame,B为服务信息DataFrame,C为用户是否更换服务系列信息
TableA (user's current service info):
cost location
John 100 Tokyo
Tom 50 Seoul
Andy 50 Seoul
Mark 80 Seoul
TableB (service info):
cost location
premium_T 100 Tokyo
basic_T 60 Tokyo
premium_S 80 Seoul
basic_S 50 Seoul
Table C (service change info):
change
John no
Tom no
Andy premium_S
Mark basic_S
使用上述数据,我想更改 Table A 中的信息,使用 Table B 和 C 中的数据。换句话说,我希望:
TableA' (modified user's service info):
cost location
John 100 Tokyo
Tom 50 Seoul
Andy 80 Seoul
Mark 50 Seoul
我使用的代码是:
TableA = pd.DataFrame(index = ['John', 'Tom', 'Andy', 'Mark'],
data = {'cost': [100,50,50,80],
'location': ['Tokyo', 'Seoul', 'Seoul', 'Seoul']})
TableB = pd.DataFrame(index = ['premium_T', 'basic_T', 'premium_S', 'basic_S'],
data = {'cost': [100, 60, 80, 50],
'location': ['Tokyo','Tokyo','Seoul','Seoul']})
TableC = pd.Series( ['no', 'no', 'premium_S', 'basic_S'], index = ['John', 'Tom', 'Andy', 'Mark'])
customer_list = TableA.index.tolist()
for k in customer_list:
if TableC.loc[k] != 'no':
TableA.loc[k] = TableB.loc[TableC.loc[k]]
代码有效,并提供了我想要的结果。
但是,我必须为一个非常大的数据集重复做这样的工作,我需要更快的方法来做这样的替换。
有什么想法吗?我认为重复使用 .loc
是问题所在,但我还没有找到可能的解决方案。我看过 pd.update()
或 pd.replace()
,但它似乎不是我要找的。
如果我们将所有内容都转换为具有命名列的数据框,我们可以使用合并来提取正确的信息:
TableA = TableA.reset_index().rename({'index': 'person'}, axis='columns')
TableB = TableB.reset_index().rename({'index': 'cost_plan'}, axis='columns')
TableC = TableC.to_frame(name='cost_plan').reset_index().rename({'index': 'person'}, axis='columns')
new_costs = TableA.merge(TableC, how='left').merge(TableB, how='left',
on=['location', 'cost_plan'],
suffixes=['_old', '_new'])
new_costs['cost_new'].fillna(new_costs['cost_old'], inplace=True)
new_costs
然后看起来像:
person cost_old location cost_plan cost_new
0 John 100 Tokyo no 100.0
1 Tom 50 Seoul no 50.0
2 Andy 50 Seoul premium_S 80.0
3 Mark 80 Seoul basic_S 50.0
首先使用 reindex
和布尔索引从 TableC
计算范围内的客户:
idx = TableC.reindex(TableA.index & TableC.index)
idx = idx[idx != 'no']
然后通过 loc
更新 TableA
:
TableA.loc[np.in1d(TableA.index, idx.index)] = TableB.reindex(idx.values).values
结果:
cost location
John 100.0 Tokyo
Tom 50.0 Seoul
Andy 80.0 Seoul
Mark 50.0 Seoul
我目前正在尝试使用另一个 DataFrame 和一系列用于我的模拟分析来替换 DataFrame 的信息。
玩具示例如下
A为用户信息DataFrame,B为服务信息DataFrame,C为用户是否更换服务系列信息
TableA (user's current service info):
cost location
John 100 Tokyo
Tom 50 Seoul
Andy 50 Seoul
Mark 80 Seoul
TableB (service info):
cost location
premium_T 100 Tokyo
basic_T 60 Tokyo
premium_S 80 Seoul
basic_S 50 Seoul
Table C (service change info):
change
John no
Tom no
Andy premium_S
Mark basic_S
使用上述数据,我想更改 Table A 中的信息,使用 Table B 和 C 中的数据。换句话说,我希望:
TableA' (modified user's service info):
cost location
John 100 Tokyo
Tom 50 Seoul
Andy 80 Seoul
Mark 50 Seoul
我使用的代码是:
TableA = pd.DataFrame(index = ['John', 'Tom', 'Andy', 'Mark'],
data = {'cost': [100,50,50,80],
'location': ['Tokyo', 'Seoul', 'Seoul', 'Seoul']})
TableB = pd.DataFrame(index = ['premium_T', 'basic_T', 'premium_S', 'basic_S'],
data = {'cost': [100, 60, 80, 50],
'location': ['Tokyo','Tokyo','Seoul','Seoul']})
TableC = pd.Series( ['no', 'no', 'premium_S', 'basic_S'], index = ['John', 'Tom', 'Andy', 'Mark'])
customer_list = TableA.index.tolist()
for k in customer_list:
if TableC.loc[k] != 'no':
TableA.loc[k] = TableB.loc[TableC.loc[k]]
代码有效,并提供了我想要的结果。
但是,我必须为一个非常大的数据集重复做这样的工作,我需要更快的方法来做这样的替换。
有什么想法吗?我认为重复使用 .loc
是问题所在,但我还没有找到可能的解决方案。我看过 pd.update()
或 pd.replace()
,但它似乎不是我要找的。
如果我们将所有内容都转换为具有命名列的数据框,我们可以使用合并来提取正确的信息:
TableA = TableA.reset_index().rename({'index': 'person'}, axis='columns')
TableB = TableB.reset_index().rename({'index': 'cost_plan'}, axis='columns')
TableC = TableC.to_frame(name='cost_plan').reset_index().rename({'index': 'person'}, axis='columns')
new_costs = TableA.merge(TableC, how='left').merge(TableB, how='left',
on=['location', 'cost_plan'],
suffixes=['_old', '_new'])
new_costs['cost_new'].fillna(new_costs['cost_old'], inplace=True)
new_costs
然后看起来像:
person cost_old location cost_plan cost_new
0 John 100 Tokyo no 100.0
1 Tom 50 Seoul no 50.0
2 Andy 50 Seoul premium_S 80.0
3 Mark 80 Seoul basic_S 50.0
首先使用 reindex
和布尔索引从 TableC
计算范围内的客户:
idx = TableC.reindex(TableA.index & TableC.index)
idx = idx[idx != 'no']
然后通过 loc
更新 TableA
:
TableA.loc[np.in1d(TableA.index, idx.index)] = TableB.reindex(idx.values).values
结果:
cost location
John 100.0 Tokyo
Tom 50.0 Seoul
Andy 80.0 Seoul
Mark 50.0 Seoul