【问题标题】:Combine two pandas df's based on a partial match根据部分匹配组合两个 pandas df
【发布时间】:2018-06-06 05:57:06
【问题描述】:

抱歉标题含糊不清,很难解释。

我有两个包含相关信息的pandas df's。一个包含显示事件应该发生时间的时间戳的数据,另一个显示事件实际发生时间的数据。

我想确定这些时间戳之间的差异。问题是代表这些事件的每个位置的值略有不同。它们相似但不相同。所以很难 merge 或 concatenate 在相同的值上。

第一个df 是事件应该发生的时间:

例子df:

Sched = pd.DataFrame({
        'E' : ['Home','Shops','Away','Shops','Home'],     
        'F' : ['10:00:00','11:00:00','12:00:00','13:00:00','14:00:00'],        
        'G' : ['No: 10', 'No: 2', 'No: 1','No: 3','No: 11'],                                 
        })

所以事件发生的地方标记在Column E中。例如Home, Shops, Away.

此 df 显示事件实际发生的时间:

Meet = pd.DataFrame({
        'A' : ['10:00:05','11:00:05','12:00:05','13:00:05','14:00:05'],
        'B' : ['HOME LOCK','AWAY HR','SHOPS JK','HOME LOCK','SHOPS JK'],
        'C' : ['No:','No:','No:','No:','No:'],         
        'D' : ['10', '1', '2','11','3'],                               
        })

所以Column B 中的数据是在同一个会议(Home、Away、Shops)中,但有一些差异。都是大写字母,还有一些额外的字符串。

我考虑过尝试在使用中映射适当的代码:

Code = pd.DataFrame({
        'H' : ['HOME LOCK','AWAY HR','SHOPS JK'],
        'I' : ['Home','Away','Shops'],                                        
        })

Meet['B'] = Meet['B'].map(Code.set_index('H')['I'])

这样我可以将输出与sched df 合并。问题是那里有数百个代码,它们每天都在不断变化。

有没有办法对值进行部分匹配?如题,大体相同的值可以合并吗?

【问题讨论】:

  • 您是否始终保证 Meet 的 B 列中的第一个单词是 Sched 的 E 列中的有效键?
  • @coldspeed 是的,第一个单词总是一样的。 Meet 总是有上限,而 Sched 不是

标签: python pandas merge concatenation


【解决方案1】:

如果第一个单词匹配,我相信可以使用 title 和 split:

Meet['E'] = Meet.B.str.title().str.split().str[0]
print (Meet)
          A          B    C   D      E
0  10:00:05  HOME LOCK  No:  10   Home
1  11:00:05    AWAY HR  No:   1   Away
2  12:00:05   SHOPS JK  No:   2  Shops
3  13:00:05  HOME LOCK  No:  11   Home
4  14:00:05   SHOPS JK  No:   3  Shops

另一种更通用的解决方案是使用extract 与| 连接的可能单词作为正则表达式或:

Meet['E'] = Meet.B.str.title().str.extract('(Home|Away|Shops)')
print (Meet)
          A          B    C   D      E
0  10:00:05  HOME LOCK  No:  10   Home
1  11:00:05    AWAY HR  No:   1   Away
2  12:00:05   SHOPS JK  No:   2  Shops
3  13:00:05  HOME LOCK  No:  11   Home
4  14:00:05   SHOPS JK  No:   3  Shops

如果通过Sched 的E 列的唯一值和\b 的单词边界创建模式应该更动态:

pat = '|'.join(r"\b{}\b".format(x) for x in Sched.E.unique())
print (pat)
\bHome\b|\bShops\b|\bAway\b

Meet['E'] = Meet.B.str.title().str.extract('(' + pat + ')')
print (Meet)
          A          B    C   D      E
0  10:00:05  HOME LOCK  No:  10   Home
1  11:00:05    AWAY HR  No:   1   Away
2  12:00:05   SHOPS JK  No:   2  Shops
3  13:00:05  HOME LOCK  No:  11   Home
4  14:00:05   SHOPS JK  No:   3  Shops

【讨论】:

  • 以前没有见过 ''.join 用于打印正则表达式模式。这将非常有帮助。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-13
  • 2019-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多