【问题标题】:How do i map a column in a dataframe using a nested dictionary?如何使用嵌套字典映射数据框中的列?
【发布时间】:2020-05-18 05:05:37
【问题描述】:

我为某些交易策略创建了这个嵌套字典,比如:

{'Strategy1' :{'AAPL':'Strategy1_APPLE', 'MSFT':'Strategy1_MICROSOFT'}, 'Strategy2' :{'AAPL': 'Strategy2_APPLE', 'MSFT':'Strategy2_MICROSOFT'}}

我已经构建了一个数据框,其中包含属于策略 1 或策略 2 的交易列表,并且已经创建了一个包含该信息的列。然后我要做的是基于顶级键(即策略1或策略2)和嵌套键(即AAPL或MSFT)将dict中的值映射到新列。这样每笔交易都伴随着正确的策略和代码在数据框的同一行中。

因此,具有 Strategy1 和 AAPL 的数据框中的一行在新列中获得了 Strategy1_APPLE 的值,但 Strategy2 和 AAPL 获得了 Strategy2_APPLE。

我一直在玩 map() 和一堆 lambda 函数,但我无法让它工作。我认为这是可能的,而不需要做一堆丑陋的循环和 if 语句,我真的可以在这里使用一些帮助来做到这一点。

编辑:示例

所以它目前看起来像这样

  ticker Strategies
1   AAPL  Strategy1
2   MSFT  Strategy1
3   MSFT  Strategy2
4   AAPL  Strategy1
5   MSFT  Strategy2

想要的结果是这样的

  ticker Strategies          substrategy
1   AAPL  Strategy1      Strategy1_APPLE
2   MSFT  Strategy1  Strategy1_MICROSOFT
3   MSFT  Strategy2  Strategy2_MICROSOFT
4   AAPL  Strategy1      Strategy1_APPLE
5   MSFT  Strategy2  Strategy2_MICROSOFT

请注意,连接字符串或类似的东西不适用于我的实际问题,因为 substgy 名称要复杂得多

【问题讨论】:

  • 我们需要一个字典使用的所有东西的例子,数据框和预期的输出
  • 也许你完全需要DataFrame.replace... 或pd.DataFrame + lookup
  • 鉴于新列中的值需要同时基于代码和策略列,我看不出这将如何工作。我看不到查找或替换如何基于多个值来做到这一点

标签: python pandas dictionary


【解决方案1】:

使用方法:

def get_substrategy(t,s):    
    v = mydict[s][t] 
    return v

然后应用 lambda:

df['substrategy'] = df.apply(lambda x: get_substrategy(x['ticker'], x['Strategies']), axis=1)

想要的结果

   ticker   Strategies  substrategy
1   AAPL    Strategy1   Strategy1_APPLE
2   MSFT    Strategy1   Strategy1_MICROSOFT
3   MSFT    Strategy2   Strategy2_MICROSOFT
4   AAPL    Strategy1   Strategy1_APPLE
5   MSFT    Strategy2   Strategy2_MICROSOFT

注意:如果策略/代码不存在,请确保在您的函数中尝试 catch

注2:没有该功能:

df['substrategy'] = df.apply(lambda x: mydict[x['Strategies']][x['ticker']], axis=1)

但您需要考虑策略/代码不存在的情况。

【讨论】:

  • 这正是我一直在寻找的,由于某种原因,我自己无法弄清楚 lambda。谢谢。
  • @Jason D. 好收获!
  • 太棒了。我刚刚花了最后的 2 1/2 试图解决这个问题。感谢您的解决方案!
  • @ciaranhaines 快乐是我的!总是乐于提供帮助。
【解决方案2】:

我将在这里使用reindex + MultiIndexd 是你的dict

df['New']=pd.DataFrame(d).stack().reindex(pd.MultiIndex.from_frame(df)).values
df
  ticker Strategies                  New
1   AAPL  Strategy1      Strategy1_APPLE
2   MSFT  Strategy1  Strategy1_MICROSOFT
3   MSFT  Strategy2  Strategy2_MICROSOFT
4   AAPL  Strategy1      Strategy1_APPLE
5   MSFT  Strategy2  Strategy2_MICROSOFT

【讨论】:

    【解决方案3】:

    这里是使用 pandas.DataFrame 构造函数的另一种方式,带有整形和merge

    d1 = (pd.DataFrame(d).rename_axis(index='ticker',columns='Strategies')
                         .stack()
                         .rename('substrategy')
                         .reset_index())
    df.merge(d1)
    

    输出:

    |    | ticker   | Strategies   | substrategy         |
    |---:|:---------|:-------------|:--------------------|
    |  0 | AAPL     | Strategy1    | Strategy1_APPLE     |
    |  1 | AAPL     | Strategy1    | Strategy1_APPLE     |
    |  2 | MSFT     | Strategy1    | Strategy1_MICROSOFT |
    |  3 | MSFT     | Strategy2    | Strategy2_MICROSOFT |
    |  4 | MSFT     | Strategy2    | Strategy2_MICROSOFT |
    

    【讨论】:

      【解决方案4】:

      如果数据框是您的目标,我建议您寻找一种更好的方式来存储您的数据。将您现有的结构转换为对数据框更友好的格式(并实现您想要的目标数据框):

      import pandas as pd
      
      # input nested dict in OP
      source_dict = {'Strategy1' :{'AAPL':'Strategy1_APPLE', 'MSFT':'Strategy1_MICROSOFT'}, 'Strategy2' :{'AAPL': 'Strategy2_APPLE', 'MSFT':'Strategy2_MICROSOFT'}}
      tmp_rows = []
      
      # convert nested-dict to pandas friendly input format
      for strategy in source_dict.keys():
          for ticker in source_dict[strategy].keys():
              substrategy = source_dict[strategy][ticker]
              tmp_rows.append({'ticker': ticker, 'Strategies': strategy, 'substrategy': substrategy})
      
      # create output dataframe
      output_dataframe = pd.DataFrame(tmp_rows)
      
      print(output_dataframe.head(10))
      

      【讨论】:

        猜你喜欢
        • 2015-07-24
        • 2021-12-08
        • 2020-11-05
        • 1970-01-01
        • 2014-06-30
        • 1970-01-01
        • 2013-04-30
        • 2021-07-14
        • 2020-03-23
        相关资源
        最近更新 更多