【问题标题】:Quickly replacing information of a pandas dataframe using other dataframe and series使用其他数据框和系列快速替换熊猫数据框的信息
【发布时间】:2018-09-07 11:04:03
【问题描述】:

我目前正在尝试使用另一个 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  

使用上述数据,我想更改表 A 中的信息,使用表 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(),但似乎不是我要找的。​​p>

【问题讨论】:

  • 一个最小的例子,例如Table1 = pd.DataFrame(...) 可能也有帮助,然后人们可以复制/粘贴而不是猜测
  • 我会添加修改谢谢
  • 我猜@AlexanderMcFarlane 建议最好分享Table1.to_dict()
  • 我做了修改..这是你的意思吗?很抱歉给您带来不便
  • TableC实际上是一个系列,还是可以是一个数据框?

标签: python pandas dataframe performance pandas-loc


【解决方案1】:

首先使用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

【讨论】:

  • 非常感谢您的解决方案!该代码显着提高了我的代码的性能。再次感谢您!
【解决方案2】:

如果我们将所有内容都转换为具有命名列的数据框,我们可以使用合并来提取正确的信息:

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

【讨论】:

  • 非常感谢您的解决方案!通过使用你的方法,我想我可以用更少的时间创建一个更大的数据框。谢谢!
猜你喜欢
  • 1970-01-01
  • 2022-06-24
  • 2020-10-21
  • 1970-01-01
  • 1970-01-01
  • 2019-12-09
  • 2022-06-15
  • 1970-01-01
  • 2022-01-11
相关资源
最近更新 更多