首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Pandas :如何在key1.str.endswith上合并2个数据帧(Key2)

Pandas :如何在key1.str.endswith上合并2个数据帧(Key2)
EN

Stack Overflow用户
提问于 2015-03-20 22:46:36
回答 3查看 253关注 0票数 1

我想找到在key1.str.endswith(key2)上合并两个数据帧的最佳方法,示例有时比文字更好:

代码语言:javascript
运行
复制
 i want to merge df1 and df2  on product.str.endswith(color)

 df1:
    index product
    1     a208-BLACK 
    2     a2008-WHITE
    3     x307-PEARL-WHITE
    4     aa-b307-WHITE

 df2:
    index color       code
    1     BLACK       X1001
    2     WHITE       X7005
    3     PEARL-WHITE X7055

要获得以下信息:

代码语言:javascript
运行
复制
 df:
    index product            code
    1     a208-BLACK         X1001
    2     a2008-WHITE        X7005
    3     x307-PEARL-WHITE   X7055
    4     aa-b307-WHITE      X7005

有什么想法吗?

EN

回答 3

Stack Overflow用户

发布于 2015-03-20 23:09:52

我不是正则表达式专家,最后一个是最难处理的,但下面是工作:

代码语言:javascript
运行
复制
In [402]:

df['code'] = df['product'].str.split('-').str[1:].str.join('-').str.findall(r'[A-Z]+').str.join('-').map(df1.set_index('color')['code'])
df
Out[402]:
                product   code
index                         
1            a208-BLACK  X1001
2           a2008-WHITE  X7005
3      x307-PEARL-WHITE  X7055
4         aa-b307-WHITE  X7005

基本上,我在-上拆分产品代码,并将所有元素放在第一个破折号的右侧。

剩下的就是:

代码语言:javascript
运行
复制
In [403]:

df['product'].str.split('-').str[1:]
Out[403]:
index
1               [BLACK]
2               [WHITE]
3        [PEARL, WHITE]
4         [b307, WHITE]
Name: product, dtype: object

然后我把破折号放回去,使用正则表达式只查找大写字母字符,这将处理最后一个字符,再次重新加入。

最后一位是在设置颜色列的索引后,在另一个df上调用map,这将在df中执行颜色值的查找并返回相应的代码。

正则表达式不是万无一失的,但它适用于您的数据集。

编辑

我现在意识到我们不需要那么多的连接:

代码语言:javascript
运行
复制
In [409]:

df['code'] = df['product'].str.findall(r'[A-Z]+').str.join('-').map(df1.set_index('color')['code'])
df
Out[409]:
                product   code
index                         
1            a208-BLACK  X1001
2           a2008-WHITE  X7005
3      x307-PEARL-WHITE  X7055
4         aa-b307-WHITE  X7005

计时

代码语言:javascript
运行
复制
In [414]:


%%timeit 
import re
df['color'] = df['product'].apply(lambda x: re.sub('^[^ALPHA:]*-(.*)', '\\1', x))

pd.merge(df, df1, on='color')
1 loops, best of 3: 4.09 ms per loop
In [416]:

%%timeit
df['code'] = df['product'].str.findall(r'[A-Z]+').str.join('-').map(df1.set_index('color')['code'])

100 loops, best of 3: 1.63 ms per loop

str方法比使用lambda快2倍以上,这并不奇怪,因为像调用map一样,str方法是矢量化的。

已更新计时

代码语言:javascript
运行
复制
In [7]:

%%timeit
df1['color'] = df1['product'].str.extract(r'-([A-Z-]+)$')
pd.merge(df1, df2)
100 loops, best of 3: 4.51 ms per loop
In [9]:

%%timeit
df1['code'] = df1['product'].str.findall(r'[A-Z]+').str.join('-').map(df2.set_index('color')['code'])
100 loops, best of 3: 3.87 ms per loop
In [10]:

%%timeit 
import re
df1['color'] = df1['product'].apply(lambda x: re.sub('^[^ALPHA:]*-(.*)', '\\1', x))

pd.merge(df1, df2, on='color')
100 loops, best of 3: 4.79 ms per loop

所以@unutbu的回答比@beaveau上校的略快一些,但在这里使用map更快。

事实上,如果我们将@unutbu的regex str方法与map结合起来,我们会比我原来的方法更快:

代码语言:javascript
运行
复制
In [12]:

%%timeit
df1['product'].str.extract(r'-([A-Z-]+)$').map(df2.set_index('color')['code'])
100 loops, best of 3: 2.17 ms per loop

因此,在这里使用map几乎比合并快2倍

票数 2
EN

Stack Overflow用户

发布于 2015-03-20 23:30:44

一些简明的解决方案:

代码语言:javascript
运行
复制
import pandas as pd

df1['color'] = df1['product'].apply(lambda x: re.sub('^[^ALPHA:]*-(.*)', '\\1', x))

pd.merge(df1, df2, on='color')

#            product        color   code
#0        a208-BLACK        BLACK  X1001
#1       a2008-WHITE        WHITE  X7005
#2  x307-PEARL-WHITE  PEARL-WHITE  X7055
#3     aa-b307-WHITE        WHITE  X7005
票数 1
EN

Stack Overflow用户

发布于 2015-03-21 06:31:25

您可以使用带有正则表达式模式r'-([A-Z-]+)$'vectorized string method str.extract来查找颜色。

代码语言:javascript
运行
复制
df1['color'] = df1['product'].str.findall(r'-([A-Z-]+)$').str[0]

然后,pd.merge(df1, df2)将在公共列(在本例中为color列)上合并:

代码语言:javascript
运行
复制
result = pd.merge(df1, df2)

例如,

代码语言:javascript
运行
复制
import io
import pandas as pd

df1 = '''\
index product
1     a208-BLACK 
2     a2008-WHITE
3     x307-PEARL-WHITE
4     aa-b307-WHITE'''
df1 = pd.read_table(io.BytesIO(df1), sep='\s+', index_col=0)

df2 = '''\
index color       code
1     BLACK       X1001
2     WHITE       X7005
3     PEARL-WHITE X7055'''
df2 = pd.read_table(io.BytesIO(df2), sep='\s+', index_col=0)
df1['color'] = df1['product'].str.extract(r'-([A-Z-]+)$')
print(pd.merge(df1, df2))

收益率

代码语言:javascript
运行
复制
            product        color   code
0        a208-BLACK        BLACK  X1001
1       a2008-WHITE        WHITE  X7005
2     aa-b307-WHITE        WHITE  X7005
3  x307-PEARL-WHITE  PEARL-WHITE  X7055

正则表达式模式r'-([A-Z-]+)$'意味着

代码语言:javascript
运行
复制
-              # match a literal hyphen
(              # followed by a group 
 [A-Z-]+       # of 1-or-more capital letters or hyphens
)              # end of group 
$              # followed by end of line
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29169310

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档