与字典映射匹配的每一行都有重复的数据框行

时间:2019-07-11 14:46:41

标签: python pandas

我不确定标题的字词,所以希望它有点清楚。

我想要的是此数据框和一个映射:

       isin        date  val
SE0000195570  2014-10-23  1
SE0000195570  2014-07-16  2
SE0000195570  2014-04-29  3
SE0000195570  2014-01-31  4          
SE0000191827  2018-10-19  5
SE0000191827  2018-07-11  6
SE0000191827  2018-04-20  7
SE0000191827  2018-02-16  8

mapping = {
  'SE0000195570': [1,2], 
  'SE0000191827': [4,5,6]
}

我想产生这个输出。

       isin        date   sec   val
SE0000195570  2014-10-23    1    1
SE0000195570  2014-10-23    2    1
SE0000195570  2014-07-16    1    2
SE0000195570  2014-07-16    2    2
SE0000195570  2014-04-29    1    3
SE0000195570  2014-04-29    2    3
SE0000195570  2014-01-31    1    4
SE0000195570  2014-01-31    2    4

SE0000191827  2018-10-19    4    5
SE0000191827  2018-10-19    5    5
SE0000191827  2018-10-19    6    5
SE0000191827  2018-07-11    4    6
SE0000191827  2018-07-11    5    6
SE0000191827  2018-07-11    6    6
SE0000191827  2018-04-20    4    7
SE0000191827  2018-04-20    5    7
SE0000191827  2018-04-20    6    7
SE0000191827  2018-02-16    4    8
SE0000191827  2018-02-16    5    8
SE0000191827  2018-02-16    6    8

如您所见,SE0000195570SE0000191827的每一行已针对其各自映射中的每个元素重复了一次。在某种程度上,我向主键添加了新列,并相应地调整了帧大小。

我尝试仅将新列sec添加到索引,但这没有任何用处。我对如何有效地做到这一点有些困惑。循环可能不是一种选择,因为我的最终表将超过一百万行。

2 个答案:

答案 0 :(得分:1)

创建df后进行交叉连接

s=pd.DataFrame(list(mapping.values()), index=mapping.keys()).stack().reset_index(level=0)
df.merge(s,left_on='isin',right_on='level_0')

答案 1 :(得分:1)

类似于Ben对dict理解和看家的回答:

m_df = (pd.concat(pd.Series(v, index=[k]*len(v)) 
                           for k,v in mapping.items()
                ).to_frame(name='sec'))

# same merge
df.merge(m_df, left_on='isin', right_index=True)

输出:

           isin        date  val  sec
0  SE0000195570  2014-10-23    1    1
0  SE0000195570  2014-10-23    1    2
1  SE0000195570  2014-07-16    2    1
1  SE0000195570  2014-07-16    2    2
2  SE0000195570  2014-04-29    3    1
2  SE0000195570  2014-04-29    3    2
3  SE0000195570  2014-01-31    4    1
3  SE0000195570  2014-01-31    4    2
4  SE0000191827  2018-10-19    5    4
4  SE0000191827  2018-10-19    5    5
4  SE0000191827  2018-10-19    5    6
5  SE0000191827  2018-07-11    6    4
5  SE0000191827  2018-07-11    6    5
5  SE0000191827  2018-07-11    6    6
6  SE0000191827  2018-04-20    7    4
6  SE0000191827  2018-04-20    7    5
6  SE0000191827  2018-04-20    7    6
7  SE0000191827  2018-02-16    8    4
7  SE0000191827  2018-02-16    8    5
7  SE0000191827  2018-02-16    8    6