. : : ClassiClub ForuM : : .

会员中心 论坛帮助 日历事件 标记论坛已读
返回   精品技术论坛 » 技术论坛 » 『软件使用』

『软件使用』: 电脑软件推荐, 电脑软件使用, 经验分享



发表新主题 回复
 
主题工具
nh_wzg
 
nh_wzg 的头像
核心会员
 
资 料:
注册日期: Jul 2000
帖子: 3,579 声望值: 3
精华: 5,解答: 10
#1 旧 2021-01-27, 18:31:46 默认 【讨论】字符串,以分组正则,多次匹配,在python_pandas下面的一种处理流程
nh_wzg 当前离线  

对字符串中,应用含分组正则,多次匹配,生成列表,取数据的方式请教?

需求:
字符串是表格中的一个单元格内容,用python读进来后,想把字符串的一系列参数给提出出来。

参考表格样式就是:str(原始信息),
需要提取出:a0(提出第1个参数),a1(提出第1个参数的单位),a2(提出第2个参数),a3(提出第2个参数的单位),a4(提出第3个参数),a5(提出第3个参数的单位),a6(提出第4个参数),a7(提出第4个参数的单位)

样例:生成的代码由 https://regex101.com/ 参考生成

代码:
# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility

import re

regex = r"(\d+)(m3/h)|(\d+)(pa)|(\d+)(kw)|(\d+)(r/min)"

test_str = ("轴流通风机 JSFT1-1 风量:35000m3/H,全压:770Pa,功率:11kW(380V),转速:1450r/min\n")

matches = re.finditer(regex, test_str, re.MULTILINE | re.IGNORECASE)

for matchNum, match in enumerate(matches, start=1):
    
    print ("Match {matchNum} was found at {start}-{end}: {match}".format(matchNum = matchNum, start = match.start(), end = match.end(), match = match.group()))
    
    for groupNum in range(0, len(match.groups())):
        groupNum = groupNum + 1
        
        print ("Group {groupNum} found at {start}-{end}: {group}".format(groupNum = groupNum, start = match.start(groupNum), end = match.end(groupNum), group = match.group(groupNum)))

aa = re.findall(regex, test_str, re.MULTILINE | re.IGNORECASE)

# Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.
aa为一个list:
代码:
[('35000', 'm3/H', '', '', '', '', '', ''),
 ('', '', '770', 'Pa', '', '', '', ''),
 ('', '', '', '', '11', 'kW', '', ''),
 ('', '', '', '', '', '', '1450', 'r/min')]
现在想把test_str 列所在datafram行值,提取出,'35000','m3/H', '770', 'Pa', '11', 'kW', '1450', 'r/min',分别对应新增加的8个列中。

aa[0]是一个tuple.

aa[0][0]='35000'
aa[0][1]='m3/H'
aa[1][2]='770'
aa[1][3]='Pa'
aa[2][4]='11'
aa[2][5]='kW'
aa[3][6]='1450'
aa[3][7]='r/min'

用两个循环嵌套的方式可以用赋值实现,由test_str 列所在datafram行值,提取出,'35000','m3/H', '770', 'Pa', '11', 'kW', '1450', 'r/min',分别对应新增加的8个列中。

但想更快捷的方式,有没有?

想象,每行的tuple数据,全部往第一行上面,引入,形成提取数据的8个列值。

菜鸟求助,请有经验的朋友不吝指点 !

===
https://www.runoob.com/regexp/regexp-syntax.html
https://www.runoob.com/w3cnote/reg-l...ookbehind.html

{'通[信讯]':'通[\u4e00-\u9fa5]*([^\u4e00-\u9fa5]\S+)'} 匹配通讯屏TX,主要是考虑中文字与型号为西文的区别
{'变压器':'(\Bs.*kva)'} 匹配【scbscb13-1600kva】,主要是scb中中间开始:\B,考虑s11类别

此帖于 2021-04-18 23:28:02 被 nh_wzg 编辑. .


平和精确简约应成为精品成员的三大基本要求!!!
nh_wzg
回复时引用此帖
闪亮
 
闪亮 的头像
终极会员
 
资 料:
注册日期: Aug 2001
帖子: 10,410 声望值: 7
精华: 2,解答: 16
#2 旧 2021-01-27, 19:52:11 默认
闪亮 当前离线  

需要这么麻烦吗?直接每行数据提取成一个list不好吗?
比如说提取后
aa=['35000','m3/H', '770', 'Pa', '11', 'kW', '1450', 'r/min']
调用就用aa[0],aa[1]这样不就好了?

另外,如果数据量不是特别大,半小时内能跑完的话,就不要折腾了。能满足工作需求就可以。


宝贝宝贝笑一笑 笑容其实很美妙
只要天天没烦恼 其他一切不重要
回复时引用此帖
nh_wzg
 
nh_wzg 的头像
核心会员
 
资 料:
注册日期: Jul 2000
帖子: 3,579 声望值: 3
精华: 5,解答: 10
#3 旧 2021-01-27, 20:00:40 默认
nh_wzg 当前离线  

引用:
作者: 闪亮 查看帖子
需要这么麻烦吗?直接每行数据提取成一个list不好吗?比如说提取后aa=['35000','m3/H', '770', 'Pa', '11', 'kW', '1450', 'r/min']调用就用aa[0],aa[1]这样不就好了?另外,如果数据量不是特别大,半小时内能跑完的话,就不要折腾了。能满足工作需求就可以。......
这个就是想要的,方便给个完整的做参考学习不?

===vim
在选定的所有行后面,增加【'】,知道定位范围,用7,15s/$/'/g,如果是定长的,用visual模式,A,Esc完成
在行内快速移动到【\】,知道在第3位置,[3f/],不知在何,[f/]到第1位置,[;]正向移动,[,]反向移动 https://zhuanlan.zhihu.com/p/30132173
直接到284行,【284gg】/【284G】/【:284回车】
直接到80列位置,【80|】
s/str1/str2/g 替换当前行中所有 str1 为 str2.
:r! type a1_20210420 读入当前屏幕显示出来的内容到文件内。

此帖于 2021-04-30 02:44:25 被 nh_wzg 编辑. .
回复时引用此帖
nightcat
 
nightcat 的头像
合作伙伴
 
资 料:
注册日期: Aug 2002
帖子: 556 声望值: 4
精华: 0,解答: 9
#4 旧 2021-01-27, 20:34:17 默认
nightcat 当前在线  

直接,号分割一下就容易了呀。
回复时引用此帖
midi
 
midi 的头像
超级会员
 
资 料:
注册日期: Oct 2001
帖子: 1,125 声望值: 3
精华: 5,解答: 35
#5 旧 2021-01-27, 21:31:39 默认
midi 当前离线  

用正则的话,这样不行吗:
https://regex101.com/r/RUtF08/1
回复时引用此帖
nh_wzg
 
nh_wzg 的头像
核心会员
 
资 料:
注册日期: Jul 2000
帖子: 3,579 声望值: 3
精华: 5,解答: 10
#6 旧 2021-01-27, 21:43:35 默认
nh_wzg 当前离线  

引用:
作者: nightcat 查看帖子
直接,号分割一下就容易了呀。
样例字符串还相对比较规范,主要想提高下对类似的不规范信息数据,进行提取的学习。

1、大致想提取的数据有目标。比如样例的对象是风机,设备应该有的参数:风压、风量、功率是基本参数,然后可能还有附加的参数。比如是双速风机、防爆风机,这些又会有额外的参数

2、获取的信息片断的特点是:不完整,不规范,可能会出现额外的参考信息

3、提取参数的流程与研究设备参数的过程类似:

3.1、先基础参数,用单位进行锚定,获取数据,(规范化参数)

3.2、后扩展未取部分内容,进行扩大的分析,调整【3.1】上面的正则匹配表达式,增加【3.1】上面的取数据范围。

3.3、固定分析出来的数据单位,供下一次的使用。

【样例01】文件没有压缩,直接把文件后后缀【.7z】删除就是原来的xls文件。

代码:
# @onda
a1='e:\样例01.xls'

import pandas as pd
f1=pd.ExcelFile(a1)
fs1=f1.sheet_names
#fs1

## a1
f09=f1.parse(sheet_name=fs1[0],header=None) #XX系统
f09[1]
f09[1][1] is the test_str to parse

====参考===
1、update boolean index 行的方式:at/iat
https://re-thought.com/how-to-change...das-dataframe/
文章中update无效的方式,可以用at来提取index,在源df中进行更新。

2、上面用正则findall语句提取出的数据,是一个list,可以用DataFrame(list)来直接进行转换。后面就是pandas的操作了
https://datatofish.com/list-to-dataframe/
上传的附件
文件类型: 7z 样例01.xls.7z (20.0 KB, 2 次查看)

此帖于 2021-04-05 17:12:29 被 nh_wzg 编辑. .
回复时引用此帖
nh_wzg
 
nh_wzg 的头像
核心会员
 
资 料:
注册日期: Jul 2000
帖子: 3,579 声望值: 3
精华: 5,解答: 10
#7 旧 2021-04-29, 13:19:38 默认
nh_wzg 当前离线  

引用:
作者: 闪亮 查看帖子
需要这么麻烦吗?直接每行数据提取成一个list不好吗?比如说提取后aa=['35000','m3/H', '770', 'Pa', '11', 'kW', '1450', 'r/min']调用就用aa[0],aa[1]这样不就好了?另外,如果数据量不是特别大,半小时内能跑完的话,就不要折腾了。能满足工作需求就可以。......
嘿嘿,有经验的朋友,没空理菜鸟,只能自己慢慢摸索。

代码:
import os
import re
import numpy as np
import pandas as pd

regex = r"(^.*)(?=L)|([\d\.]+)(rpm)|([\d\.]+)(m3/h)|([\d\.]+)(pa)|([\d\.]+)(kw)"
test_str='SPF-5F-01、05 L=35100m3/h h=550pa n=11kw 2900rpm'
matches = re.findall(regex, test_str, re.MULTILINE | re.IGNORECASE)
df1=pd.DataFrame(matches)
df1
matches的输出结果是:
代码:
[('SPF-5F-01、05 ', '', '', '', '', '', '', '', ''),
('', '', '', '35100', 'm3/h', '', '', '', ''),
('', '', '', '', '', '550', 'pa', '', ''),
('', '', '', '', '', '', '', '11', 'kw'),
('', '2900', 'rpm', '', '', '', '', '', '')]
df1的输出结果是:
代码:
        0        1        2        3        4        5        6        7        8
0        SPF-5F-01、05                                                               
1                                35100        m3/h                               
2                                                550        pa               
3                                                                11        kw
4                2900        rpm
df1结果中,显示为空的值是""
代码:
df1.iloc[0,1]==""
结果是:True

这个显示为空的”“值的处理,困扰了很久,isna(),isnull()对这个""值的单元无效。
代码:
for i in df1:
    if i=="":
        i=None
这样处理,也是无效。

最后还是在stackoverflow上面看到这样一个讨论:
《How to set a cell to NaN in a pandas dataframe》
https://stackoverflow.com/questions/...frame/34794525

代码:
df1.replace({'':None},inplace=True)
df1=df1.fillna(method='backfill')
df1.drop(df1[df1[0].isna()].index,inplace=True)
df1
最终得到df1的结果是:
代码:
	0	1	2	3	4	5	6	7	8
0	SPF-5F-01、05	2900	rpm	35100	m3/h	550	pa	11	kw
dataframe columns的赋值语句,预定数据类型,可以预确定的,尽量预先确定。具体就是新增加的列,尽量采用assign的语句进行定义。
然后在后面的循环语句中,再进行填充。不然数据类型的不同,就可能导致出错。

此帖于 2021-04-30 06:54:32 被 nh_wzg 编辑. .
回复时引用此帖
发表新主题 回复

标签
python, regex, vim

主题工具

论坛规则  发帖规则
不可以发表主题
不可以回复帖子
不可以上传附件
不可以编辑自己的帖子
论坛启用 vB 代码
版面启用 表情符号
版面启用 [IMG] 代码
版面禁用 HTML 代码


所有时间均为北京时间, 现在的时间是 09:57:16.

本论坛带宽由迅通网络提供
SSL证书由TrustAsia提供

Copyright © 2000 - 2019 ClassiClub Forum All Rights Reserved.
粤ICP备09123456号