熊猫数据框中的列级解析
Posted
技术标签:
【中文标题】熊猫数据框中的列级解析【英文标题】:Column level parsing in pandas data frame 【发布时间】:2019-08-01 10:33:19 【问题描述】:目前我正在处理 5 列的 2000 万条记录。我的数据框看起来像 -
tran_id id code
123 1 1759@1@83@0#1362@0.2600@25.7400@2.8600#1094@1@129.6@14.4
254 1 1356@0.4950@26.7300@2.9700
831 2 1354@1.78@35.244@3.916#1101@2@40@0#1108@2@30@0
732 5 1430@1@19.35@2.15#1431@3@245.62@60.29#1074@12@385.2@58.8#1109
141 2 1809@8@75.34@292.66#1816@4@24.56@95.44#1076@47@510.89@1110.61
期望的输出 -
id new_code
1 1759
1 1362
1 1094
1 1356
2 1354
2 1101
2 1108
5 1430
5 1431
5 1074
5 1109
2 1809
2 1816
2 1076
到目前为止我做了什么 -
import re
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
dd= pd.DataFrame('col' : d["code"].apply(lambda x: re.split('[# @ ]', x)))
dd.head()
s = dd['col'].str[:]
dd= pd.DataFrame(s.values.tolist())
dd.head()
cols = range(len(list(dd)))
num_cols = len(list(dd))
new_cols = ['col' + str(i) for i in cols]
dd.columns = new_cols[:num_cols]
请记住数据的大小是巨大的......2000万。不能做任何循环。
提前致谢
【问题讨论】:
【参考方案1】:您可以使用Series.str.findall
提取分隔符之间长度为 4 的整数:
#https://***.com/a/55096994/2901002
s = df['code'].str.findall(r'(?<![^#])\d4(?![^@])')
#alternative
#s = df['code'].str.replace('[#@]', ' ').str.findall(r'(?<!\S)\d4(?!\S)')
然后通过numpy.repeat
和str.len
创建新的DataFrame 并通过chain.from_iterable
展平:
from itertools import chain
df = pd.DataFrame(
'id' : df['id'].values.repeat(s.str.len()),
'new_code' : list(chain.from_iterable(s.tolist()))
)
print (df)
id new_code
0 1 1759
1 1 1362
2 1 1094
3 1 1356
4 2 1354
5 2 1101
6 2 1108
7 5 1430
8 5 1431
9 5 1074
10 5 1109
11 2 1809
12 2 1816
13 2 1076
【讨论】:
在s.str.len()
更改为s.str.len().astype(np.int64)
?
我没有改变任何东西..我的代码如下 - df = pd.DataFrame( 'id' : df['id'].values.repeat(s.str.len() ), 'new_code' : list(chain.from_iterable(s.tolist())) ) df.head(20) 目前我正在处理完整的数据集...这是一个原因吗?有些值的格式不同
如果使用df = pd.DataFrame( 'id' : df['id'].values.repeat(s.str.len().astype(np.int64)), 'new_code' : list(chain.from_iterable(s.tolist())) )
也会出现同样的错误?
@NikitaAgarwal - 如果我的回答有帮助,请不要忘记accept。谢谢。【参考方案2】:
另一种使用 Series.str.extractall
和不同正则表达式模式的方法:
(df.set_index('id').code.str.extractall(r'(?:[^\.]|^)(?P<new_code>\d4)')
.reset_index(0)
.reset_index(drop=True)
)
[出]
id new_code
0 1 1759
1 1 1362
2 1 1094
3 1 1356
4 2 1354
5 2 1101
6 2 1108
7 5 1430
8 5 1431
9 5 1074
10 5 1109
11 2 1809
12 2 1816
13 2 1076
14 2 1110
【讨论】:
以上是关于熊猫数据框中的列级解析的主要内容,如果未能解决你的问题,请参考以下文章