有字符串(是pandas
数据框的行):
2.5807003.49 9/2020 24,54 4.7103181.69 9 /2020 172,05 4.7197189.46 09/2020 172,0 5 4.7861901.25 9/2020 8 9,16
2.5807003.49 10/2020 35,65 4.7103181.69 10/2020 185,50 4.7197189.46 1 0/2020 185,5 0 4.7861901.25 10/2020 94 ,32
我需要从这些行中提取以下信息(这里的逗号是小数分隔符):
order_id date sum
2.5807003.49 09/2020 24,54
4.7103181.69 09/2020 172,05
4.7197189.46 09/2020 172,05
4.7861901.25 09/2020 89,16
2.5807003.49 10/2020 35,65
4.7103181.69 10/2020 185,50
4.7197189.46 10/2020 185,50
4.7861901.25 10/2020 94,32
- 只有 4 个不同的
order_id
,它们始终具有相同的结构; date
中的月份可以有一位或两位数;- 日期本身可能(也可能不包含)空格! 例如
9 /2020
或9/2020
,10/2020
或1 0/2020
; sum
,
后面总是有两个数字,但不幸的是,可能(或不包含)也包含空格:24,54
、172,0 5
、185,5 0
、94 ,32
。
我是这样想的: 第一步是拆分订单。 显然,与给定order_id
相关的信息由,
锚定 - 每行有 4 个订单和 4 个逗号。 因此,找到逗号,然后在逗号后面前进两位数字(不考虑空格),最后回头看直到行首或前一个顺序的结尾。 但即使在这里,我也被困住了,因为我不明白如何捕获逗号后的两位数字,而不管空格(如果有的话)。
输入 df
vals
0 2.5807003.49 9/2020 24,54 4.7103181.69 9 /2020 172,0 5 4.7197189.46 09/2020 172,0 5
1 4.7861901.25 9/2020 8 9,16
2 2.5807003.49 10/2020 35,65 4.7103181.69 10/2020 185,50 4.7197189.46 1 0/2020 185,5 0
3 4.7861901.25 10/2020 94 ,32
现在,由于预期 df 中的多行在原始 df 中合并为一行,因此最好先将整个vals
列转换为单个字符串
str1 = "n".join(df['vals'].values)
str1
2.5807003.49 9/2020 24,54 4.7103181.69 9 /2020 172,0 5 4.7197189.46 09/2020 172,0 5
4.7861901.25 9/2020 8 9,16
2.5807003.49 10/2020 35,65 4.7103181.69 10/2020 185,50 4.7197189.46 1 0/2020 185,5 0
4.7861901.25 10/2020 94 ,32
现在使用findall
获取所有最终记录。所有三个必需列都位于单独的捕获组中。order_id
([d.]+)
.由于它没有空间,所以它是直截了当的。date
(ds?d?s?/s?(?:ds?){3}d)
空间可以位于日期中的任何位置。sum
是逗号后有两个数字的[ds]+,s?ds?d)
。
req_vals = re.findall(r'([d.]+)s*(ds?d?s?/s?(?:ds?){3}d)s*([ds]+,s?ds?d)',str1)
req_vals
[('2.5807003.49', '9/2020', '24,54'),
('4.7103181.69', '9 /2020', '172,0 5'),
('4.7197189.46', '09/2020', '172,0 5'),
('4.7861901.25', '9/2020', '8 9,16'),
('2.5807003.49', '10/2020', '35,65'),
('4.7103181.69', '10/2020', '185,50'),
('4.7197189.46', '1 0/2020', '185,5 0'),
('4.7861901.25', '10/2020', '94 ,32')]
最后,在输出数据帧中,可以删除空间。
final_df = (pd.DataFrame(req_vals, columns=['order_id', 'date', 'sum'])
.replace(r's', '', regex=True))
final_df
order_id date sum
0 2.5807003.49 9/2020 24,54
1 4.7103181.69 9/2020 172,05
2 4.7197189.46 09/2020 172,05
3 4.7861901.25 9/2020 89,16
4 2.5807003.49 10/2020 35,65
5 4.7103181.69 10/2020 185,50
6 4.7197189.46 10/2020 185,50
7 4.7861901.25 10/2020 94,32
一个可用于提供的示例的正则表达式:
(2.5807003.49|4.7103181.69|4.7197189.46|4.7861901.25)s+([ds]+/d{4})s+([ds]+,[ds]+)(?:s|$)
演示:https://regex101.com/r/VLc53D/1/
或者,如果一年中可以有一个空间:
(2.5807003.49|4.7103181.69|4.7197189.46|4.7861901.25)s+([ds]+/[ds]+)s+([ds]+,[ds]+)(?:s|$)
演示:https://regex101.com/r/LjcF3Q/1/