【问题标题】:How to efficiently replace partial strings in pandas?如何有效地替换熊猫中的部分字符串?
【发布时间】:2017-09-10 16:04:58
【问题描述】:

目标:根据提供给我的内容重新格式化 pandas 数据框的内容。

我有以下数据框:

我希望用以下样式更改每一列:

我正在使用下面的代码来生成我需要的样式,但是效率不高:

lt = []
for i in patterns['Components'][0]:
    for x in i.split('__'):
        lt.append(x)
lt[1].replace('(','').replace(', ',' < '+str(lt[0])+' ≤ ').replace(']','')

我尝试Pandas Replace 无济于事 - 它不会引发任何错误,而且似乎忽略了我的目标。

【问题讨论】:

  • 都是string类型的列吗?当你type(df.Components.iloc[0]) 时你会得到什么?
  • 非空对象

标签: regex string python-3.x pandas replace


【解决方案1】:

来源 DF:

In [37]: df
Out[37]:
                           Components                             Outcome
0          (Quantity__(0.0, 16199.0])  (UnitPrice__(-1055.648, 3947.558])
1  (UnitPrice__(-1055.648, 3947.558])          (Quantity__(0.0, 16199.0])

解决方案:

In [38]: cols = ['Components','Outcome']
    ...: df[cols] = df[cols].replace(r'\(([^_]*)__\(([^,\s]+),\s*([^\]]+)\]\).*',
    ...:                             r'\2 < \1 <= \3',
    ...:                             regex=True)

结果:

In [39]: df
Out[39]:
                          Components                            Outcome
0          0.0 < Quantity <= 16199.0  -1055.648 < UnitPrice <= 3947.558
1  -1055.648 < UnitPrice <= 3947.558          0.0 < Quantity <= 16199.0

更新:

In [113]: df
Out[113]:
                                Components                               Outcome
0             (Quantity__(0.0, 16199.0])     (UnitPrice__(-1055.648, 3947.558])
1    (UnitPrice__(-1055.648, 3947.558])             (Quantity__(0.0, 16199.0])

In [114]: cols = ['Components','Outcome']

In [115]: pat = r'\s*\(([^_]*)__\(([^,\s]+),\s*([^\]]+)\]\)\s*'

In [116]: df[cols] = df[cols].replace(pat, r'\2 < \1 <= \3', regex=True)

In [117]: df
Out[117]:
                          Components                            Outcome
0          0.0 < Quantity <= 16199.0  -1055.648 < UnitPrice <= 3947.558
1  -1055.648 < UnitPrice <= 3947.558          0.0 < Quantity <= 16199.0

或不带括号:

In [119]: df
Out[119]:
                         Components                           Outcome
0         Quantity__(0.0, 16199.0])  UnitPrice__(-1055.648, 3947.558]
1  UnitPrice__(-1055.648, 3947.558]          Quantity__(0.0, 16199.0]

In [120]: pat = r'([^_]*)__\(([^,\s]+),\s*([^\]]+)\]'

In [121]: df[cols] = df[cols].replace(pat, r'\2 < \1 <= \3', regex=True)

In [122]: df
Out[122]:
                          Components                            Outcome
0         0.0 < Quantity <= 16199.0)  -1055.648 < UnitPrice <= 3947.558
1  -1055.648 < UnitPrice <= 3947.558          0.0 < Quantity <= 16199.0

【讨论】:

  • 您的解决方案看起来很棒,但我只取回数据框的原始结果(没有什么新东西)。如果重要的话,Pandas 数据框中的原始结果 (['Components','Outcome']) 都是非空对象。
  • @Student,这意味着您的真实数据(字符串)略有不同,并且您的样本数据集不可重现 - 因为 RegEx 适用于您的样本 DF 而不适用于您的真实数据....您能否提供一个可重现的样本数据集(文本格式,以便我们复制粘贴)?
  • 我运行了以下命令:patterns['Components'][0],df['Components'][0] 产生了以下结果:(frozenset({'Quantity__(0.0, 16199.0]'} ), '(Quantity__(0.0, 16199.0])')。我不确定这是否有帮助,但我所拥有的只是原始数据帧(模式)的输出。因为您推测这两个数据帧可能不一样(而且它们不是基于 patterns=df=False),我试图用 patterns.replace('(^\s+|\s+$)', '', regex=True, inplace=True) 来清理东西。在目前,这对输出没有任何影响。有什么想法吗?
【解决方案2】:
import pandas as pd
import re
data=pd.DataFrame({'components':
['(quantity__(0.0,16199.0])','(unitprice__(-1055.648,8494.557])'],'outcome':
['(unitprice__(-1055.648,8494.557])','quantity__(0.0,16199.0])']})


def func(x):
    x=str(x)
    x=x.split('__')
    dx=x[0].replace("(",'')
    mt=re.findall('\d*\.\d*',x[1])
    return('{}<{}<={}'.format(dx,mt[0],mt[1]))


df=data.applymap(func)
print(df)

【讨论】:

    猜你喜欢
    • 2017-09-09
    • 2017-07-08
    • 2019-06-03
    • 2018-02-24
    • 2017-03-12
    • 2019-11-23
    • 2019-02-06
    • 1970-01-01
    • 2017-11-17
    相关资源
    最近更新 更多